Ага, спасибо. Тут ещё пришло в голову, почему такой разрыв в смертности может быть — в большом городе пострадавшего с тяжёлыми травмами можно успеть спасти с большей вероятностью, чем вдали от города, где и ждать помощи дольше, и до больницы везти дольше.
Единичный контр-пример, он в принципе не работает для каких-то выборок/корреляций/паттернов, основанных на статистических данных.
Это бесспорно так, но, всё же, только в случае серьёзных научных исследований, а не в контексте данной статьи. Мне кажется, здесь велика доля субъективного мнения автора, а статистика, приведённая автором, вполне себе спорная. Например, когда автор приводит результаты своих замеров количества миганий "аварийкой", не указан ни размер выборки, ни география исследования (а ведь от региона к региону поведение водителей может сильно отличаться). Поэтому контр-примеры и интересны.
Если статистически, то вы, полагаю, правы. Но я про себя писал, а я, видать, в статистике где-то на краях распределения.
Конкретно же с Матизами у меня есть эпичные случаи, не надо их недооценивать) Не далее как сегодня утром, в левом ряду на загородной трассе, догоняет меня машина, и быстро так, сильно быстрее потока; пропускаю вперёд — а это Матиз! А ещё, пару лет назад было: еду по КАДу в предпоследнем ряду (слева ещё один ряд свободный), боковой ветер такой силы, что аж чувствуешь, как машину сносит — и слева опережает Матиз, за рулём девушка, руль одной рукой держит, другой губы красит)
Я один раз обычно мигаю, потому что: а) кому предназначено - моё "спасибо" увидит; б) кому не предназначено — того мигающая аварийка не смутит и не запутает; в) сделав быстрый клик-клик, я точно не забуду выключить аварийку (а такие забывшие бывают, смущают прочих участников движения, и потенциально приводят к авариям, ведь кто-то может решить, что у авто с аварийкой проблемы, и не будет ожидать резкого ускорения/манёвра).
А это где географически такое явление наблюдается? В СПб/Ленобласти такой проблемы не вижу (если про ночь разговор). А днём можно, ПДД разрешает использовать ПТФ вместо ближнего света в светлое время суток.
Это, наверное, от индивидуальных особенностей восприятия зависит. Неоднократно слышал от знакомых, что отношение к ним на дороге отличается, смотря на какой машине они едут (в том духе что пересядешь на машину поменьше, и тебя "меньше уважают", пропускают реже, и т.п). А я такого не замечаю вообще, на какой бы машине не ехал. Сам езжу примерно одинаково (от настроения стиль езды явно сильнее зависит, чем от машины), и к остальным участникам движения отношусь вроде бы равнозначно (по крайней мере, я так думаю, а там кто знает, если снаружи посмотреть).
А можно источник информации про Берлин 2019? Я с ходу не нашёл, но нашёл про всю Германию: в 2019 было 3059 смертей в ДТП. В России в 2019 году смертей в ДТП было 16.9 тыс. С учётом разницы в населении получается, что смертность примерно в 4 раза отличается, не в 10. Если данные верны, могу только предположить, что Берлин по какой-то причине выделяется безопасностью среди прочих городов Германии, либо что основные смертельные ДТП на автобанах происходят, а не в городах.
Я имел в виду что-то вроде такого: компилятор автоматически вставляет ловлю ошибки, если функция возвращает std::error<type>, и при этом компилятор не видит обработки ошибки пользователем перед использованием значения (а также опциональное отключение такого поведения под ответственность программиста).
std::error<int> foo => std::error<int>(0,"Error!\n",100);
void bar()
{
std::error<int> result = foo();
// Здесь нет проверки на ошибку перед использованием результата,
// и компилятор здесь вставил её сам, не требуя от программиста try.
... тут result используется ...
result = foo();
result.catch();
...
// А здесь есть проверка. Компилятор ничего от себя не добавлял.
... тут result используется ...
unsafe
{
result = foo();
// Здесь нет проверки на ошибку перед использованием результата,
// но программист явно указал компилятору не проверять.
... тут result используется ...
}
}
Идея в том, что проверка на ошибку, всегда добавляемая по умолчанию, лучше чем отсутствие проверки по умолчанию: программист не забудет добавить try где нужно. Если же программист точно уверен, что никакая проверка не нужна, он указывает это явно.
Наблюдения интересные. Про прижимание к впереди едущему и за собой замечал. А можно вот эту фразу пояснить, пожалуйста:
а потом просто смотрим салоны (ведь динамику и шумоизоляцию через фото не передать) и всё становится ясно.
Я чую, что здесь ещё один слой восприятия есть (возможно, только мне непонятный), так как мне ничего ясно не становится. Если чисто про ассоциации от внешнего вида салона, то фото первого у меня с дешёвым китайским пластиковым магнитофоном ассоциируется, а второго - с пафосной дорогой Hi-Fi техникой европейского бренда. Что именно во внешнем виде должно намекать на "драйв"?
То есть, предполагается, что программист должен окружать блоком try любой код, где ошибки не проверяются вручную, если он хочет, чтобы программа завершалась "красиво", c runtime error в месте вызова? Но учитывая, что исключений нет, получается, блоком try вообще все функции закрывать желательно. Почему бы тогда просто не сделать это поведение всегда активным по умолчанию, и добавить спецификатор для функции, которым можно пользоваться, если дефолтные проверки не нужны? Тогда и исключения из правил для блока try не нужно будет, и самого try. Или, как альтернативу, заместо try можно блок а-ля unsafe добавить, который работает строго наоборот. Мне кажется, это как-то более правильно было бы.
Я по большей части соглашусь, заметная часть артефактов тех времён тоже не нравится, все эти волны/помехи/смазывание (я так понимаю, большей частью из-за дешёвых трактов/кабелей, а в консолях и преобразования в RF и обратно). Но когда с этим делом более-менее нормально, а контент подходящий, как в этой статье, то картинка на трубке мне нравится. Наверное, всё это вкусовщина, спорить не готов. Собственно, и у меня тоже пристрастия со временем менялись.
Интересно, спасибо. Я истории Defender в таких деталях не знал.
Кстати, тут недавно в комментах к другой статье всплывал факт, что многие фанаты старых игровых систем ищут ЭЛТ-мониторы. И здесь в статье есть хорошая иллюстрация, почему так. Как же обалденно смотрится Defender на ролике с живого автомата! И как грустновато выглядит, если его в эмуляторе запустить. Из игры будто жизнь пропадает, всё как-то плоско, пресно, даже не знаю с чем сравнить, как еда без соли, наверное. Для таких старых игр, почти без графики, с чёрным фоном, ЭЛТ придавал "спецэффекты", вроде засветок и послесвечения, которое только добавляло "космической" атмосферы и плавности процессу. Как лазеры и частицы на ЭЛТ выглядят - обалденно же. В современных играх такое нужно специально делать, а тогда - оно "бесплатное" было.
Этого очень не хватает, когда играешь в эмуляторах на современных экранах. Я видел попытки эмулировать олдскульную ЭЛТ-картинку в эмуляторах постпроцессингом, но как-то всё не то. Часто это просто попытки эмуляции аналогового растра, по факту добавляющие размытость. А вот чтобы glow и послесвечение эмулировалось, такого пока не встречал. Может, где-то такое реализовали, а я не знаю?
Попытки сделать "улучшенный Си" мне интересны, и название языка вы классное выбрали, мне нравится (но, кажется, в контексте ЯП оно несколько, ээ, двусмысленное).
Есть несколько вопросов, а поскольку я не нашёл ответов ни в документации на сайте (как-то совсем уж там мало), ни на гитхабе, поэтому поинтересуюсь тут.
void* a; // Переменные автоматически инициализируются в null(можно отключить)
a = itop(void*,0); // Ошибка
int b;
std::scanf("%d",&b);
a = itop(void*,b); // Если b == 0 - runtime ошибка
b = ptoi(a);
Конструкции языка itop и ptoi это что за сущности? Выглядят как функции, но itop, например, принимает первым параметром тип, и при этом как-то узнаёт адрес переменной, переданной вторым параметром значению (может, это ссылка)? Или это всё-таки не функции в обычном понимании, а спец. конструкции самого языка?
std::error<int> func => std::error<int>(10,"",0);
Я так понимаю, что сущность std::error<> предполагается возвращать всем функциям, предполагающим возможность фейла в процессе выполнения. Это известный подход к выдаче и обработке ошибок, и он мне в целом импонирует, но мне кажется название неудачное выбрано. Может, что-то нейтральное, навроде std::result было бы лучше, ведь предполагается, что ф-я всё-таки не ошибку возвращать должна, а результат (который да, может быть не посчитан из-за ошибки) .
try {
int base = func();
}
// base виден во всей функции
Я правильно понимаю, что этот случай (блок try) является исключением из правила "переменная объявленная внутри блока, видна только там"? Вообще, обработка ошибок мне не очень понятна, try/catch смущают, наверное: вроде как исключение ловим, но не исключение, дальше уровнем оно не пробрасывается, соответственно, не очень понятно вообще, зачем пытаться быть похожим на обработку исключений, в том числе и ключевые слова копируя. Лично мне наверное зашло бы что-то попроще, в духе:
auto result = func();
if (!result.err) doSomethingWith(result.val);
и если бы проверки не было, а result.val использовался, вот тогда бы генерировался runtime error.
Ещё можно попробовать кнопки не снизу (под кодом) располагать, а сбоку. Тогда ответы будут видны всегда, а перемотка останется только для кода, если он по высоте не влезет.
Даже неандертальцев на планете мы не оставили, потому что они были слишком непохожими на нас.
Это старый развенчанный миф. В те времена свободы и равенства, когда люди жили маленькими кучками, все в чём-то были непохожи на соседей, и убивали/кушали тогда все всех примерно одинаково. Кроманьонцы неандертальцев "специально" не геноцидили. Есть признаки того, что неандертальцы даже поагрессивнее были, чем наши предки. Исчезли неандертальцы по естественным причинам, оказавшись менее приспособленными к жизни в меняющихся условиях, но при этом, за десятки тысяч лет совместного проживания, успев поскрещиваться с кроманьонцами, и оставить современным европейцам приличную часть своих генов. Т.е., каком-то смысле они даже не то чтобы вымерли, а "растворились" в нас.
P.S. Возмутился данной фразой и немного не дочитал до места в статье, где всё-же есть намёк на оправдательный приговор нашим предкам ввиду отсутствия доказательств совершения преступления )
Вопреки распространенному мнению, почти не существует реальных свидетельств того, что неандертальцы были уничтожены в результате жестокого геноцида, совершенного нашими древними предками.
У нас на предприятии так видеоролик снимали. С одной стороны всё настоящее, настоящие программисты за настоящими рабочими местами, и т.д. Но снять "просто", как мы хотели, не дали) Обстановку прибрали, рабочие места разгребли, сотрудников накрасили причесали, сказали сделать вид, что усиленно трудимся над задачей, и затем снимали кино в несколько дублей. А, да, ещё все, кто в кадр попадёт, подписали договор, что они участвуют съёмке в роли актёров и т.д. В итоге, как по мне, получилось неестественно и наиграно (ещё бы, сотрудников-то "актёры" играют), хотя по факту всё без обмана.
Как любитель старых консолей, подтверждаю. И дело даже не в чёткости/разрешении, а в принципе работы. Аналоговый видеосигнал выдавался с частотой 50/60 Гц, но полукадрами. В одном полукадре чётные линии кадра, в следующем - нечётные, и т.д. Прикол в том, что консоли этим пользовались, и выдавали настоящие 60 FPS, формируя полукадры не из одного кадра, а каждый раз разные. Куча эффектов были на этом основаны, например, полупрозрачная тень: в одном полукадре рисуем, в другом пропускаем, из-за высокой частоты и послесвечения люминофора кажется, что тень полупрозрачная. А современные телевизоры в большинстве своём такой видеосигнал обрабатывают так: склеивают чётный полукадр с нечётным в один кадр, и выдают его с частотой 25/30 Гц (ещё хорошо, если склеивают, некоторые телевизоры, такое ощущение, что один полукадр просто выкидывают). Что в итоге? Внесена задержка как минимум на 1/60 секунды, а тень или чёрная, или вообще отсутствует (если игра по-какому-то своему таймингу вывод делала, а телевизору "повезло" склеить как раз те полукадры, где тень не отрисовывалась). Ну и плавность потеряна, FPS в два раза просел. Возможно, и есть современные телевизоры, которые с таким справятся как ожидается, но я пока не встречал.
Есть предложение доработать окошко с заданиями, чтобы оно ресайзилось так, чтобы в него влезало задание со всеми вариантами ответа, а скролл был не нужен. Сейчас перематывать приходится почти всегда. Из-за этого в самый первый раз я неверный ответ тыкнул - под заданием только одна кнопка помещалась, а она очень на окошко ввода похожа, я тыкнул, удивился результату, и только в этот момент осознал, что это не окошко ввода, а кнопка, и что справа ещё и скролл есть.
Спасибо за статью, написано приятно, узнал кое-что новое.
А в игрушке специально столько пауэрапов повсюду раскидано и задания проходятся даже если неправильно ответить? Как-то слишком лайтово, похардкорнее бы. Программист на плюсах должен быть фрустрационно стоек )
Ага, спасибо. Тут ещё пришло в голову, почему такой разрыв в смертности может быть — в большом городе пострадавшего с тяжёлыми травмами можно успеть спасти с большей вероятностью, чем вдали от города, где и ждать помощи дольше, и до больницы везти дольше.
Это бесспорно так, но, всё же, только в случае серьёзных научных исследований, а не в контексте данной статьи. Мне кажется, здесь велика доля субъективного мнения автора, а статистика, приведённая автором, вполне себе спорная. Например, когда автор приводит результаты своих замеров количества миганий "аварийкой", не указан ни размер выборки, ни география исследования (а ведь от региона к региону поведение водителей может сильно отличаться). Поэтому контр-примеры и интересны.
Если статистически, то вы, полагаю, правы. Но я про себя писал, а я, видать, в статистике где-то на краях распределения.
Конкретно же с Матизами у меня есть эпичные случаи, не надо их недооценивать) Не далее как сегодня утром, в левом ряду на загородной трассе, догоняет меня машина, и быстро так, сильно быстрее потока; пропускаю вперёд — а это Матиз! А ещё, пару лет назад было: еду по КАДу в предпоследнем ряду (слева ещё один ряд свободный), боковой ветер такой силы, что аж чувствуешь, как машину сносит — и слева опережает Матиз, за рулём девушка, руль одной рукой держит, другой губы красит)
Если не ошибаюсь, Федеральный закон № 173-ФЗ от 10.12.2003 «О валютном регулировании и валютном контроле».
Я один раз обычно мигаю, потому что: а) кому предназначено - моё "спасибо" увидит; б) кому не предназначено — того мигающая аварийка не смутит и не запутает; в) сделав быстрый клик-клик, я точно не забуду выключить аварийку (а такие забывшие бывают, смущают прочих участников движения, и потенциально приводят к авариям, ведь кто-то может решить, что у авто с аварийкой проблемы, и не будет ожидать резкого ускорения/манёвра).
А это где географически такое явление наблюдается? В СПб/Ленобласти такой проблемы не вижу (если про ночь разговор). А днём можно, ПДД разрешает использовать ПТФ вместо ближнего света в светлое время суток.
Это, наверное, от индивидуальных особенностей восприятия зависит. Неоднократно слышал от знакомых, что отношение к ним на дороге отличается, смотря на какой машине они едут (в том духе что пересядешь на машину поменьше, и тебя "меньше уважают", пропускают реже, и т.п). А я такого не замечаю вообще, на какой бы машине не ехал. Сам езжу примерно одинаково (от настроения стиль езды явно сильнее зависит, чем от машины), и к остальным участникам движения отношусь вроде бы равнозначно (по крайней мере, я так думаю, а там кто знает, если снаружи посмотреть).
А можно источник информации про Берлин 2019? Я с ходу не нашёл, но нашёл про всю Германию: в 2019 было 3059 смертей в ДТП. В России в 2019 году смертей в ДТП было 16.9 тыс. С учётом разницы в населении получается, что смертность примерно в 4 раза отличается, не в 10. Если данные верны, могу только предположить, что Берлин по какой-то причине выделяется безопасностью среди прочих городов Германии, либо что основные смертельные ДТП на автобанах происходят, а не в городах.
Я имел в виду что-то вроде такого: компилятор автоматически вставляет ловлю ошибки, если функция возвращает std::error<type>, и при этом компилятор не видит обработки ошибки пользователем перед использованием значения (а также опциональное отключение такого поведения под ответственность программиста).
Идея в том, что проверка на ошибку, всегда добавляемая по умолчанию, лучше чем отсутствие проверки по умолчанию: программист не забудет добавить try где нужно. Если же программист точно уверен, что никакая проверка не нужна, он указывает это явно.
Наблюдения интересные. Про прижимание к впереди едущему и за собой замечал. А можно вот эту фразу пояснить, пожалуйста:
Я чую, что здесь ещё один слой восприятия есть (возможно, только мне непонятный), так как мне ничего ясно не становится. Если чисто про ассоциации от внешнего вида салона, то фото первого у меня с дешёвым китайским пластиковым магнитофоном ассоциируется, а второго - с пафосной дорогой Hi-Fi техникой европейского бренда. Что именно во внешнем виде должно намекать на "драйв"?
То есть, предполагается, что программист должен окружать блоком try любой код, где ошибки не проверяются вручную, если он хочет, чтобы программа завершалась "красиво", c runtime error в месте вызова? Но учитывая, что исключений нет, получается, блоком try вообще все функции закрывать желательно. Почему бы тогда просто не сделать это поведение всегда активным по умолчанию, и добавить спецификатор для функции, которым можно пользоваться, если дефолтные проверки не нужны? Тогда и исключения из правил для блока try не нужно будет, и самого try. Или, как альтернативу, заместо try можно блок а-ля unsafe добавить, который работает строго наоборот. Мне кажется, это как-то более правильно было бы.
Я по большей части соглашусь, заметная часть артефактов тех времён тоже не нравится, все эти волны/помехи/смазывание (я так понимаю, большей частью из-за дешёвых трактов/кабелей, а в консолях и преобразования в RF и обратно). Но когда с этим делом более-менее нормально, а контент подходящий, как в этой статье, то картинка на трубке мне нравится. Наверное, всё это вкусовщина, спорить не готов. Собственно, и у меня тоже пристрастия со временем менялись.
Интересно, спасибо. Я истории Defender в таких деталях не знал.
Кстати, тут недавно в комментах к другой статье всплывал факт, что многие фанаты старых игровых систем ищут ЭЛТ-мониторы. И здесь в статье есть хорошая иллюстрация, почему так. Как же обалденно смотрится Defender на ролике с живого автомата! И как грустновато выглядит, если его в эмуляторе запустить. Из игры будто жизнь пропадает, всё как-то плоско, пресно, даже не знаю с чем сравнить, как еда без соли, наверное. Для таких старых игр, почти без графики, с чёрным фоном, ЭЛТ придавал "спецэффекты", вроде засветок и послесвечения, которое только добавляло "космической" атмосферы и плавности процессу. Как лазеры и частицы на ЭЛТ выглядят - обалденно же. В современных играх такое нужно специально делать, а тогда - оно "бесплатное" было.
Этого очень не хватает, когда играешь в эмуляторах на современных экранах. Я видел попытки эмулировать олдскульную ЭЛТ-картинку в эмуляторах постпроцессингом, но как-то всё не то. Часто это просто попытки эмуляции аналогового растра, по факту добавляющие размытость. А вот чтобы glow и послесвечение эмулировалось, такого пока не встречал. Может, где-то такое реализовали, а я не знаю?
Попытки сделать "улучшенный Си" мне интересны, и название языка вы классное выбрали, мне нравится (но, кажется, в контексте ЯП оно несколько, ээ, двусмысленное).
Есть несколько вопросов, а поскольку я не нашёл ответов ни в документации на сайте (как-то совсем уж там мало), ни на гитхабе, поэтому поинтересуюсь тут.
Конструкции языка itop и ptoi это что за сущности? Выглядят как функции, но itop, например, принимает первым параметром тип, и при этом как-то узнаёт адрес переменной, переданной вторым параметром значению (может, это ссылка)? Или это всё-таки не функции в обычном понимании, а спец. конструкции самого языка?
Я так понимаю, что сущность std::error<> предполагается возвращать всем функциям, предполагающим возможность фейла в процессе выполнения. Это известный подход к выдаче и обработке ошибок, и он мне в целом импонирует, но мне кажется название неудачное выбрано. Может, что-то нейтральное, навроде std::result было бы лучше, ведь предполагается, что ф-я всё-таки не ошибку возвращать должна, а результат (который да, может быть не посчитан из-за ошибки) .
Я правильно понимаю, что этот случай (блок try) является исключением из правила "переменная объявленная внутри блока, видна только там"? Вообще, обработка ошибок мне не очень понятна, try/catch смущают, наверное: вроде как исключение ловим, но не исключение, дальше уровнем оно не пробрасывается, соответственно, не очень понятно вообще, зачем пытаться быть похожим на обработку исключений, в том числе и ключевые слова копируя. Лично мне наверное зашло бы что-то попроще, в духе:
и если бы проверки не было, а result.val использовался, вот тогда бы генерировался runtime error.
Ещё можно попробовать кнопки не снизу (под кодом) располагать, а сбоку. Тогда ответы будут видны всегда, а перемотка останется только для кода, если он по высоте не влезет.
Это старый развенчанный миф. В те времена свободы и равенства, когда люди жили маленькими кучками, все в чём-то были непохожи на соседей, и убивали/кушали тогда все всех примерно одинаково. Кроманьонцы неандертальцев "специально" не геноцидили. Есть признаки того, что неандертальцы даже поагрессивнее были, чем наши предки. Исчезли неандертальцы по естественным причинам, оказавшись менее приспособленными к жизни в меняющихся условиях, но при этом, за десятки тысяч лет совместного проживания, успев поскрещиваться с кроманьонцами, и оставить современным европейцам приличную часть своих генов. Т.е., каком-то смысле они даже не то чтобы вымерли, а "растворились" в нас.
P.S. Возмутился данной фразой и немного не дочитал до места в статье, где всё-же есть намёк на оправдательный приговор нашим предкам ввиду отсутствия доказательств совершения преступления )
У нас на предприятии так видеоролик снимали. С одной стороны всё настоящее, настоящие программисты за настоящими рабочими местами, и т.д. Но снять "просто", как мы хотели, не дали) Обстановку прибрали, рабочие места разгребли, сотрудников
накрасилипричесали, сказали сделать вид, что усиленно трудимся над задачей, и затем снимали кино в несколько дублей. А, да, ещё все, кто в кадр попадёт, подписали договор, что они участвуют съёмке в роли актёров и т.д. В итоге, как по мне, получилось неестественно и наиграно (ещё бы, сотрудников-то "актёры" играют), хотя по факту всё без обмана.Как любитель старых консолей, подтверждаю. И дело даже не в чёткости/разрешении, а в принципе работы. Аналоговый видеосигнал выдавался с частотой 50/60 Гц, но полукадрами. В одном полукадре чётные линии кадра, в следующем - нечётные, и т.д. Прикол в том, что консоли этим пользовались, и выдавали настоящие 60 FPS, формируя полукадры не из одного кадра, а каждый раз разные. Куча эффектов были на этом основаны, например, полупрозрачная тень: в одном полукадре рисуем, в другом пропускаем, из-за высокой частоты и послесвечения люминофора кажется, что тень полупрозрачная. А современные телевизоры в большинстве своём такой видеосигнал обрабатывают так: склеивают чётный полукадр с нечётным в один кадр, и выдают его с частотой 25/30 Гц (ещё хорошо, если склеивают, некоторые телевизоры, такое ощущение, что один полукадр просто выкидывают). Что в итоге? Внесена задержка как минимум на 1/60 секунды, а тень или чёрная, или вообще отсутствует (если игра по-какому-то своему таймингу вывод делала, а телевизору "повезло" склеить как раз те полукадры, где тень не отрисовывалась). Ну и плавность потеряна, FPS в два раза просел. Возможно, и есть современные телевизоры, которые с таким справятся как ожидается, но я пока не встречал.
Есть предложение доработать окошко с заданиями, чтобы оно ресайзилось так, чтобы в него влезало задание со всеми вариантами ответа, а скролл был не нужен. Сейчас перематывать приходится почти всегда. Из-за этого в самый первый раз я неверный ответ тыкнул - под заданием только одна кнопка помещалась, а она очень на окошко ввода похожа, я тыкнул, удивился результату, и только в этот момент осознал, что это не окошко ввода, а кнопка, и что справа ещё и скролл есть.
Спасибо за статью, написано приятно, узнал кое-что новое.
А в игрушке специально столько пауэрапов повсюду раскидано и задания проходятся даже если неправильно ответить? Как-то слишком лайтово, похардкорнее бы. Программист на плюсах должен быть фрустрационно стоек )
P.S.
Тут точка с запятой в конце строки пропущена.