компиляция самых странных решений в js / it-юмор :: geek (Прикольные гаджеты. Научный, инженерный и айтишный юмор)

it-юмор geek 

компиляция самых странных решений в js

£ typeof NaN <• "number"
>	9999999999999999 <• 10000000000000000
>	0.5+0.1==0.6 <• true
>	0.1+0.2==0.3 <• false
£ Math.max()
<* -Infinity
>	Math.min()
<• Infinity
>	[]+[]
• i ••
» []+{>
<• "[object Object]"
> {}+[]
<• 0
>	true+true+true===3 <• true
>	true-true
<• 0
£ true==l <•
Подробнее
£ typeof NaN <• "number" > 9999999999999999 <• 10000000000000000 > 0.5+0.1==0.6 <• true > 0.1+0.2==0.3 <• false £ Math.max() <* -Infinity > Math.min() <• Infinity > []+[] • i •• » []+{> <• "[object Object]" > {}+[] <• 0 > true+true+true===3 <• true > true-true <• 0 £ true==l <• true £ true===l <• false > (• + [] + [] + *П) -length <• 9 > 9+"l" <• "91" > 91-"1" <• 90 > [ ] ==0 true Спасибо за изобретение JavaScript
it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Еще на тему
Развернуть
Никак не могу придумать случай, когда вообще может понадобиться динамическая типизация...
Иисyc Иисyc 13.05.202001:23 ответить ссылка -0.2
Динамическая типизация есть везде. Например, ты можешь сложить int и float, хотя это разные типы с разным представлением. И в зависимости от порядка сложения, ты получишь на выходе или int, или float - это даже породило отвратительный паттерн типа *1.0
Hellsy Hellsy 13.05.202002:05 ответить ссылка -1.5
Это ты про строгую или слабую типизацию, например в Си, как ты сказал можно сложить int и float, благодаря безопасному согласованию типов и положить в long если хочешь.
А динамическая это когда ты вначале обьявил int a = 0, а потом a = "test string" и всё ок, теперь а - строка.
И я о том же. Мне вот за "любителем" динамической типизации приходится говно разгребать... то был массив как массив, а нет, он как парижская мадемуазель то стринг, то инт.
В Си для этого есть указатели, которые могут указывать на все, что тебе вздумается и никакой проверки в рантайме ни на что нет.
Hellsy Hellsy 13.05.202023:06 ответить ссылка -0.6
не во всех. В некоторых современных языках такого нет - например в swift ты даже не сможешь Float и CGFloat сложить, не то что Int.
Пример языка, где её нет — Rust (playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=add5e25b9528a67015330258eab4c504 ).
Запрещено:
1 + 0.1 — складывать целое с дробным
1u32 + 1u16 и 1.0f32 + 1.0f64 — типы разной ширины
let z: *const u32 = &8u16 — присваивать указатели или ссылки разных типов (ссылка в указатель того же типа — разрешено, обратно — запрещено, т.к. ссылка, в отличие от указателя, не может быть нулевой)
Тем не менее, можно писать 1 as _ + 0.1 as _ — тогда компилятор преобразует типы в какой-то общий, но только при условии, что подходит только один тип, иначе ошибка автовыведения.
Получаешь на вход данные с третьей стороны (из файла или по api) в виде строки (xml, json, yaml) - как вообще можно работать с этими данными без возможности на ходу собрать структуру (массив, объект) с нужным набором полей, их типов и значений?
temoffey temoffey 13.05.202002:11 ответить ссылка -1.3
Ну, типа, теоретически ты пишешь модель или интерфейс, а потом привязываешь данные к ней.

Забавно, но на JS тоже есть библиотеки, поддерживающие привязку объектов к моделям - там класс-модель дополняется декораторами.
Hellsy Hellsy 13.05.202002:20 ответить ссылка 1.6
"данные с третьей стороны" - структура данных изначально может быть неизвестна, либо известна но не полностью.
Разве не для этого проверки и существуют?
Что бы что то проверить, надо что то загнать в память, а что загонять на этапе компиляции/написаниякода/простановкитипов неизвестно.
Вот только не нужно начинать. В твоём случае мы получаем строку. А я говорю о случаях, когда мы НЕ используем данные из вне.
Я всего лишь предложил вариант на "Никак не могу придумать случай".
js разрабатывался с учётом простоты работы с хтмл, текстом и не плодить кучу переменных как в серьёзных проектах. Сейчас, конечно, он сильно разросся и старое наследие сильно мешает современным программистам.
let price = getFromServer();
...
price = '<strong>$ ' + price + '</strong>';
let data = getJSON();
...
data = getFromJSON(data, 'носки');
...
data = 'Состав изделия: ' + data.composition;
При нормальном подходе к разработке подобные случаи не должны проявляться: в других языках для больших чисел не используют int, не сравнивают напрямую между собой дробные числа, полученные математическими операциями, не используют функции без аргументов где эти аргументы явно подразумеваются. Зачем совершать математические действия над объектами? в случае неоднозначностей очень желательно приводить типы (что есть обязательным в других языках и непонятны подгорания по этому поводу в отношении JS)
Думаю тут как и с html пытались добиться отказоустойчивости. Типо не существует невалидного html - всегда что то да покажется, а в js даже деление на 0 не ошибка.
да, это тоже. в большинстве современных сайтов десятки ошибок в консоли вылазят. при компиляции ни один проект бы на других языках не собрался бы.
Хуяк-хуяк и сайт готов.
Perl. Динамическая типизация по сравнению с которой JS - очень строгий язык. Передавай в функции все, что хочешь и как хочешь, включая автоматический перенос локальных переменных. И до кучи позволяет переопределять любые "математические" операции как для отдельных классов, так и глобально.
Hellsy Hellsy 13.05.202023:12 ответить ссылка 0.0
а это правда, что на перле можно скомпилить рандомный набор символов?
Конечно. Мы так и пишем на нем. Потом ищем того, кому надо то, что получилось.
Hellsy Hellsy 14.05.202023:09 ответить ссылка 0.7
В смысле "как"? Они приходят в виде строки (твои слова), со строкой и работаешь. Вспомни школьные задачи типа получить из строки "12345" число 12345 не прибегая к встроенным функциям конвертации.
Это конечно теоретический вариант, не предлагаю использовать серьезно на практике.
Эта строка представляет собой не просто числовое или строковое значение, но объект любого уровня сложности и вложенности.

Пример JSON:

{
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]
}

Это объект типа ключ-значение, в котором ключу "employees" соответствует значение типа массив из объектов, которые в свою очередь содержат пары ключ-значение с для ключей "firstName" и "lastName"
Hellsy Hellsy 13.05.202002:34 ответить ссылка 0.0
Все еще не понимаю в чем проблема. Когда ты используешь динамическую типизацию разве программа не парсит такую строку, отталкиваясь от скобок, создает дерево или другую структуру на основе этого, с чем и работает? Вот то же самое только ручками.
И у тебя получится написанная своими руками динамическая типизация. Вопрос - нахера?
Hellsy Hellsy 13.05.202023:14 ответить ссылка 0.0
"виде строки (xml, json, yaml)" - я уточнил что строка не просто одно значение, а структура с множеством значений. Но в целом посыл понятен - работать со "строкой" как со строкой. Но это мало того что не удобно из за примитивности, бывают ситуации когда это попросту невозможно.
тут основная проблема в нелогичном преобразовании типов, что является явным проебом логики языка. А динамическую типизацию можно использовать в различных условных операциях, и для извлечения разной информации из одной переменной для других. Но, при этом, просто брать одну переменную и постоянно менять ее значение разными типами, будто это какай-то общественный сортир, - это признак худшего говнокода, который только можно придумать.
Давайте запилим на вашем типизированном языке какой-нибудь quicksort для интов. А потом quicksort для даблов. Тут мы приходим к шаблонам. И чем больше мы с ними работает тем больше понимаем что нахер их и нахер типы. Если что-то плавает как утка и крякает как утка то это можно считать за утку.
Gribs Gribs 15.05.202001:58 ответить ссылка -0.6
На самом деле большинство довольно привычно, кроме того не надо импортировать непонятные библиотеки и показывать ошибки в них
А что тут странного?

Знак == в операциях с плавающей запятой использовать нельзя в абсолютном большинстве языков, включая все языки низкого уровня.

"===" - это строгое сравнение с требованием совпадения типа, как раз для тех, у кого подгорало от конвертации чисел в строки и наоборот.
Конкретно приведенный тут случая даже описан на W3Schools:
When using the === operator, equal booleans are not equal, because the === operator expects equality in both type and value.

boolean представлен просто как числа 1 и 0, как и ээ... да в абсолютном большинстве языков и даже СУБД.

Любая операция со знаком +, проведенная не над числом, вызывает метод toString(), у массива метод .toString() выводит все его элементы через запятую. Два пустых массива, соответственно, дают две пустые строки, которые при сложении дают тоже пустую строку.
Для объекта метод toString возвращает "[object ClassName]" - в примере выше просто "[object Object]"

Любая операция со знаком - подразумевает конвертацию в число.

И всегда, когда идет конвертация, подразумевается, что программист понимает, что он делает и зачем. Если зачем-то ему понадобилось сложить три булевы переменные, то вероятно он ожидает числовой ответ, не?
Hellsy Hellsy 13.05.202001:38 ответить ссылка 5.7
>Знак == в операциях с плавающей запятой использовать нельзя в абсолютном большинстве языков, включая все языки низкого уровня.

только у других ву-языков обычно для этого есть встроенные классы и методы

>Любая операция со знаком +, проведенная не над числом, вызывает метод toString()

а в более правильных языках вываливается types mismatch

>И всегда, когда идет конвертация, подразумевается, что программист понимает, что он делает и зачем.

или же он ожидал, что придёт массив, но кое-что наебнулось и пришёл null или буль
Это какие "встроенные методы" есть у, скажем, C или Perl-а для сравнения чисел с плавающей запятой?

> а в более правильных языках вываливается types mismatch

К строкам во многих современных языках разрешено прибавлять числа.
А динамическая типизация внутри числовых типов (int, float, double) существует с доисторических времен.

> или же он ожидал, что придёт массив

От операции сложения массива с объектом посредством знака "+"? Я с трудом себе представляю подобное.
Hellsy Hellsy 13.05.202002:15 ответить ссылка 0.1
Кстати, о type mismatch и сложении "не тех типов":
hellsy cat aa.c #include <stdio.h> #include <stdbool.h>
int main() {
bool a = true;
printf("%d\n", a + a + a);
return 0;
}
hellsy gcc aa.c -o aa && ./aa && rm aa 3
hellsy |
Hellsy Hellsy 13.05.202002:22 ответить ссылка 0.0
Ну с булом так истроически вышло. Это исключение, а не правило.
int16 int16 13.05.202009:56 ответить ссылка 0.3
Нет такого понятия, как "использовать нельзя", если интерпретатор не сообщает об этом ни ошибкой выполнения, ни даже предупреждением. Даже самый лучший программист иногда допускает обычные опечатки, и вылавливать их с настолько похуистичным интерпретатором - это та еще работа.
Ошибки от интерпретатора или компилятора - это несущественная мелочь. Основные проблемы всегда лежат там, где нет никаких предупреждений и нужно просто понимать, как это работает или что может привести к ошибочному результату.
Hellsy Hellsy 13.05.202023:19 ответить ссылка -0.6
я более того скажу: реально стремные случаи тут не описаны, например та же сортировка
Wolfdp Wolfdp 13.05.202018:50 ответить ссылка 0.0
А что не так с сортировкой?
Hellsy Hellsy 13.05.202023:19 ответить ссылка -0.6
[1, 2, 3, 10].sort()

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

# хер пойми какие кейсы (например сложить бесконечность с ложью и поделить на пустоту для получения неопределености) не проблема, ибо на практике такое писать не будешь.
# динамические скрипты сами по себе то еще приключение и без таких подводных камней впервую очередь из-за отсутствия ошибок "на этапе компиляции", а в рантайме валится чаще где-то дальше проблемного места.
# два преведущих пункта не повод переставать стебятся с того факта, какую лютую дичь можно наваять на JS.
Wolfdp Wolfdp 14.05.202011:37 ответить ссылка 0.1
Я все равно не понял, в чем проблема с сортировкой. Если ты про то, что оно отсортирует по алфавиту, так это прямо в документации и написано. И в Перле так же будет.

Везде, где есть динамическая типизация, нужно указывать функцию сортировки.

Ошибки, незаметные на этапе компиляции, хорошо помогает исправить TypeScript.
Hellsy Hellsy 15.05.202018:37 ответить ссылка 0.0
Ну если так то уже скорее Интерпретация
CoDer CoDer 13.05.202001:45 ответить ссылка 0.7
и до сих пор нет этого коммента?
https://www.destroyallsoftware.com/talks/wat
Брендон не раз говорил, что у него не было адекватного времени спроектировать js - он накидал прототип "за 10 дней и 10 ночей"

Брендон возглавляет комитет по разработке WASM, и судя по динамике разработки - очень хочет искупить свои грехи
WASM стронг. Я достаточно сложные С++ проекты компилил с успехом. Вот WebGPU еще придет вообще все будет зашибись
int16 int16 13.05.202009:51 ответить ссылка 0.1
Я многое могу понять. Приведение типов, все дела.
Но во имя каких богов, Mathf.max() возвращает "минус бесконечность"
Байр Байр 13.05.202008:19 ответить ссылка 0.4
Насколько я знаю, функция работает так: внутри Math.max(a, b, c) появляется переменная max, которое в цикле сравнивается с a, b, c. Но до начала цикла проверок ему надо назначить начальное значение, которое для любых a, b, c должно быть меньше всех. Таким значением является -Infinity, любой переданный аргумент будет больше или равен. А вот если не задать аргументов, то вернется начальное значение. Думаю изначально это можно было назвать багом, но в итоге это было задокументировано и стало фичей, как к примеру typeof null === 'object'.
это не баг, это нормальная функциональность и минималистичность кода. можно было напихать кучу проверок: а что если юзер не задал аргументы? а что если только один аргумент, а что если не-числовые значения... защита от дурака получится слишком громоздкой и тормознутой
Вспомнилась история с файлами в линукс, название которых начинается на точку. Изначально не планировалось, нужно было скрыть папки . и .. А в коде просто добавили проверку на одну точку в начале имени. Как итог - механизм скрытых файлов. "можно было бы назвать багом, но"
прикольно, буду знать :)
думаю, там функция а-ля:

max = (...args) => {
let result = -Infinity

args.forEach(arg => {
if (arg > result) {
result = arg
}
})

return result
}

и минус бесконечность поставили, что бы первая проверка всегда была максимальным числом
Скорее даже просто reduce.
Hellsy Hellsy 15.05.202018:38 ответить ссылка 0.0
А почему 0.1+0.2 не равно 0.3? Должно же быть какое-то рациональное объяснение.
Проблема с представлением чисел в компьютерах. Например, в десятичной системе 1/3 ~= 0,33333... Но в реальном мире мы не можем записать бесконечное количество троек. А число 0.333..333 не полностью равно 1/3. В разных системах исчисления разные числа невозможно записать как десятичную (или скорее n-ичную дробь). Так в двоиной системе, которой пользуются компьютеры невозможно записать 0.1 и 0.2. И это не проблема js
из-за особого формата представления дробных чисел получается 0.30000000000000004
при вычислении дробных значений в большинстве языков получаются приблизительные, а не математически точные значения. для точных значений используются специальные математические библиотеки или с числами работают как со строками, что во много раз медленней, занимает гораздо больше ОЗУ.
мдэ блять
>	0.5+0.1 == 0.6
<• true
>	0.1 + e.2|
0.30000000000000004
Добро пожаловать в реальный мир, Нео.
cat aa.c && gcc aa.c -o aa && ./aa && rm aa #include <stdio.h>
#include <stdbool.h>
int main() {
printf("%.*e\n",'.', 0.2 + 0.1); return 0;
}
3.0000000000000004440892098500626161694526672363e-01
Hellsy Hellsy 13.05.202023:26 ответить ссылка 1.5
Там не со второго надо говорить блеать, а с первого. Сравнивать два float-а в нормальных ( C ) языках это false
По-моему на мемасах про джаваскипт всего его уже выучили
Я не понимаю, все эти люди которые не понимают JS, они как думают, что все языки должны быть похожи на те языки которые они уже знают? Это как учить английский и ожидать что там будут те же времена как и в русском. А потом ещё делать мемасы про то какой это странный язык. Ой, лучше буду всегда говорить на русском, он хоть понятный.
Только зарегистрированные и активированные пользователи могут добавлять комментарии.
Похожие темы

Похожие посты
Шт' ■’Ч&иЦТЩ Ш			
1 £ м »•Vfl 1 '			!j Я ХОЧУ ВЫУЧИТЬ JAVASCRIPT
/—		
> [10, 9, 8, 3, 2, 1, 0].sorto		
[0,	1, 10, 2, 3, 8, 9]	1 ' Vj *
Ч		1 ^ i
подробнее»

it-юмор geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор js сортировка

Я ХОЧУ ВЫУЧИТЬ JAVASCRIPT /— > [10, 9, 8, 3, 2, 1, 0].sorto [0, 1, 10, 2, 3, 8, 9] 1 ' Vj * Ч 1 ^ i
Jk.	Gender	Ratii
	undefined	
	male	
	female	
m	male Z typeof NaN <• "number"
>	9999999999999999 10000000000000000
>	0.5+0.1==0.6 <• true
i 0.1+0.2==0.3 <• false * Math.max()
<• -Infinity
>	Math.min()
<• Infinity
>	[]+[]
<. 11 11
> []+{}
<• "[object Object]"
> {)+[]
<• 0
> true+true+true===3 <• true
£ true==l <• true
>	true===l <• fals
подробнее»

it-юмор geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор js

Z typeof NaN <• "number" > 9999999999999999 10000000000000000 > 0.5+0.1==0.6 <• true i 0.1+0.2==0.3 <• false * Math.max() <• -Infinity > Math.min() <• Infinity > []+[] <. 11 11 > []+{} <• "[object Object]" > {)+[] <• 0 > true+true+true===3 <• true £ true==l <• true > true===l <• fals
> [6,	-2, ly
<• Array (4) [
> I
-7].sort()
-2, -7, 2, 6 ]