И C++ туда же
Подробнее
JAVASCRIPT С #include <stdio.h> #i nclude <stdbool.h> int mainC) { printf("> %d\n", 11+1); printf("> %d\n", 11 + '1'); printf("> %s\n", "11" + 1); > 12 > 60 > 1 ...БУДУ ПРОСТИТУТКОЙ
it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Еще на тему
%s проморгал, да, правда первой ошибки это не убирает.
Господи... Почему я это знаю...
Да, это другое.
Хотя в обоих случаях нужно понимать, что ты делаешь и зачем.
Разумеется, Си неидеален. Его система типов куда строже, чем у JS, но все равно очень слабая и позволяет (особенно без -Wall -Werror) отстреливать себе ноги в куче различных мест, например через неявный каст void* куда угодно.
C++ в этом плане уже лучше, особенно если писать, так скзаать, на Modern C++, с активным использованием статики и прочего компил-тайма. Но и C++ неидеален.
Дальше можно взять какой-нибудь Rust. Его система типов (во многом вдохновленная ФП-языками) еще более строгая и выразительная, и позволяет еще больше ошибок ловить. И не только ошибки по работе с памятью, чем знаменит Rust, но, к примеру, проверить что в паттерн-матчинге (некий аналог switch-case) по enum были обработаны ВСЕ возможные ветви, или что переданный в функцию параметр ТОЧНО не какой-нибудь null (Option в Rust).
Мало Rust? Боюсь, тут надо расчехлять тяжелую артиллерию. Haskell.
Мало и его? Что ж, тут уже полный пиздец, берите Irdis. Это хаскеллеподобный язык с зависимыми типами, который позволяет строить формальные доказательства корректности программ на этапе компиляции. Например, формально верифицировать, что если у вас массив и некое заранее неизвестное число, была сделана проверка, что это число не выходит за границы массива. Но это уже почти эзотерика.
Рекомендую хорошую статью на хабре: Парсите, а не валидируйте на тему того, как строгие системы типов помогут нам писать более безопасные и надежные проги.
А возвращаясь к JS, скажу, что JS заслужанно хейтят как старое легаси-говно, имеющее полтора миллиона способа отстрелить себе конечности и программировать на нем можно не благодаря, а вопреки.
Радует одно, что в индустрии есть тренд на движение в этом направлении. Тот же TypeScript (кстати, это не C# для веба, там довольно интересная система типов, как я понимаю, хоть от говно-наследия JS он не избавился), и Rust, и даже для Python, который остается динамически типизируемым, есть аннотации типов, которые могут быть использованы линтерами для проверки, что ваш код не слишком говно.
Случай из жизни: я каждый день на работе использую питон с тайп аннотациями и линтер, и заявляю, что это уже не раз спасало мою ногу и помогало в написании кода, когда прямо в IDE видишь, что пишешь хуйню.
> Хотя в обоих случаях нужно понимать, что ты делаешь и зачем.
Вот я долгое время любил C++ и писал на нем. И вроде все нормально, кроме того, что постоянно надо думать, что ты делаешь и зачем, постоянно жопа горит от того, а правильно ли ты делаешь тут, а правильно ли там, а вдруг, щас РРАААЗ - и полетели ноги, или неоптимальное копирование, и прочее говно. Вот, вроде бы, не сложно, но стопицот тыщ миллиардов вариантов в этих ваших плюсах. На Си, кстати, такого нет, ИМХО. Куча способов отстрелить себе ногу указателями, но зато Си простой как топор.
А потом я попробовал поучить Rust ради любопытства. Там свои заебы, но, оказалось, можно писать без страха.
И его система типизации не то, что строже - она лучше всего, что есть в C/C++/C#/Java, не говоря уже о популярных интерпретаторах типа Perl/PHP/Python.
В рантайме типизация простенькая (в C/C++ она, впрочем, вообще отсутствует), однако ее можно сделать строгой сторонними библиотеками через декораторы. Да и эксепшины тоже можно добавить:
Например так:
Object.prototype.toString = function() { alert('Куда, блядь?!'); return "Не делай так, мудила!"; };
let a = { };
document.write('a' + a);
А для полной анальной огороженности и паранойи придуман Redux, хотя он больше подходит любителям какого-нибудь React-a.
В общем, за многие годы работы с JS я сталкивался с неочевидным способом выстрелить себе в ногу наверное всего пару раз. Потому что ну нет там никакого особенного легаси.
При этом существует множество способов выстрелить себе в ногу, не связанных с типизацией. Почему-то никто не ноет о thread-safety и race condition, о полноценной поддержке регулярных выражений с бэктрейсом, о возможности выбора стратегии работы GC, о сложностях отладки (привет от C, с его прекрасным seg. fault - ебись с этим как хочешь), и т.д., и т.п. Складывается ощущение, что единственная проблема, которая мучает людей - это как сложить, сука, Object и Array.
Про перечисленные вами штуки я не в курсе, потому что на жс никогда толком не писал. А строгая типизация - это добро и приносит счастье. В том же питоновском проекте на работе до того, как ввели типы и линтер типов, местами была боль, потому что передавалось хуй знает что хуй знает куда. Потом оно фиксилось, но это надо ещё найти... А сколько раз раз мне IDE говорила "куда, блять, передал nullable объект, мудила, туда его нельзя" просто не сосчитать. Да и автокомплит лучше работает. Сплошные плюсы.
Основной толк от рантайм-проверок лежит в области валидации моделей. Это когда приходит неебовый JSON(или XML, или ответ от БД, или еще что-то), который надо натянуть на имеющийся под него класс, убедившись, что в полученном объекте есть все нужные поля и их значения соответствуют типам.
В JS для аналогичных функций есть библиотека ClassValidator (и не только она), которая работает... ну как-то вот так:
export class Post {
@Length(10, 20)
title: string;
@Contains("hello")
text: string;
@IsInt()
@Min(0)
@Max(10)
rating: number;
@IsDate()
createDate: Date;
}
validate(post).then(errors => ...
Это не то, чтобы прям рантайм-валидация - ее надо каждый раз запускать (можно устроить через геттеры/сеттеры, впрочем), но все-таки это способ проверить модель, получить список ошибок и что-то с этим знанием дальше делать, а не просто забить хуй, как это делают почему-то 9 из 10 разработчиков.
ЗЫ. А что, компиляторы достаточно умны, чтобы понять, что тут что-то не так, если бы функции были бы не extern? Я сейчас проверил, вроде не ругается.
2. int + char. А char - в С неявно приводится к int. Что уебанство. Поэтому к 11 прибавился ASCII код символа "1".
3. строковый литерал + int. Строка - указатель const char*. Операция "+" для указателей определена и это "увеличить указатель на sizeof". Поэтому там был напечатан второй символ строки. А это не уебанство, это адресная арифметика, и на ней живет 2/3 Си и половина С++.