Pull to refresh
38
0
Send message

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

Не холивара ради, а просто хочется уточнить. Вы утверждаете, что вторая половина 90-х была, по сравнению, с концов 80-х лучше. А фактор того, что за 90-е умерло примерно 10 миллионов человек, которые "не вписались в рынок", немалая часть эмигрировала, а остальные, по мере возможности, пилили так называемое "наследие", вынося с закрывающихся заводов все, кроме стен, вы учитываете?

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

UPD: Внес дополнение к примечанию, надеюсь, это прояснит ситуацию для тех, кто будет читать позднее.

На эту тему есть в начале и в конце ремарки. И если бы интерфейс был таким, как вы описываете, то, к примеру, сигнатура метода Add() должна была бы быть следующей:

func (c Calc) Add(operand float64) Calculator[float64]

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

UPD: Для устранения шероховатостей подправлю последний пример, дабы было понятно, что там не требуется второй параметр.

Не знаю, кто такой Егор Бугаенко, но можно как-нибудь поближе к сути: вы не согласны с моим утверждением? Если не согласны, то будьте добры, пояснить свою позицию. Это будет полезно не только мне, если я ошибаюсь, но и тем, кто будет читать комментарии.

Ну, наличие холста - уже хорошо, меня больше напрягло вот это:

go install golang.org/x/mobile/cmd/gomobile@latest
go: golang.org/x/mobile/cmd/gomobile@latest: no matching versions for query "latest"

Если кто знает решение - буду крайне благодарен.

Я еще понимаю не учитывать мобильную версию Collabora Office, но с отсутствием серверной версии у LibreOffice согласиться не могу: CODE - открытый пакет на основе LibreOffice как раз и реализует облачный вариант, интегрируется с тем же NextCloud. Раньше сам LibreOffice поддерживал возможность рендера в web, но с какого-то времени данные функции были переданы Collabora, так что это вполне официальная реализация облачной версии.

Что касается буфера обмена, то тут хотелось бы сделать вот какое замечание: в Linux он не нужен, у меня в KDE, да и, думаю, в других средах, системный буфер обмена прекрасно хранит историю, так что выносить данную функциональность в офисный пакет просто нет смысла, как мне кажется.

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

Понятно, но, думаю, вы все-таки путаете null safety и отсутствие null как такового. То, что вы описали, примерно то, что я представлял. Если не учитывать различные небезопасные преобразования, то тот же TypeScript также не позволит записать null в поле конкретным типом, как и undefined. Но если TS - надстройка, то тот же Dart вполне четко не позволяет использовать null для переменных и полей, которым явно этот тип не разрешен. Так что, принципиальной разницы нет. Другое дело, что динамические языки с null (тот же JS) позволяют его пихать куда угодно, что, безусловно, усложняет ситуацию.

А как работает option без значения null? Должен быть тогда какой-то оператор который возвращает true или false в зависимости от наличия/отсутствия значения, а также какая-то встроенная функция или оператор, которая позволяет выставить поле в неопределенное. Тогда это тоже самое, только без явного наличия значения.

Вы натягиваете сову на глобус, но это, хотя бы, весело.

Первый пример: тут вы именно используете фишку наличие типа undefined. В любом другом языке, да и в этом, решается просто:

const calc = (val1: unknown, val2: unknown):unknown => {...}
let hasPrevious = false
let previous: unknown
export const getCalcValue = (value: unknown):unknown => {
   if (!hasPrevious) {
       hasPrevious = true
       previous = value
       return value
   }

   return calc(previous, value)
}

Правда, в вашем примере меня смущает то, что previous - константа, очевидно, что ей нельзя задать присвоить значение в строке 7. Да, у нас добавилась переменная, но этот мелкий недостаток можно пережить, зато никакого UB. Также странно для меня выглядит использование типа unknown для calc, ведь его семантика в том, что мы нам не важно - что это за значение, мы просто передаем его куда-то дальше или возвращаем, но к рассматриваемому вопросу это не имеет никакого отношения.

Про второй пример вы сами все сказали, нужно сперва проверять наличие ключа в словаре, а потом уже получать значение свойства, либо делать это так (хотя проверка поля в данном случае предпочтительней):

class A {}
const insts:Record<string, A> = {}
export default function getInstByName(name: string):A {
  let instance;
  
  try {
    instance = insts[name];
  } catch (e) {
    instance = new A();
    insts[name] = instance;
  }

  return instance;
}

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

Внес в текст некоторые пояснения, в том числе - упоминание валидации. Надеюсь, это улучшит текст.

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

По поводу контракта с обязательным полем тут уже в комментариях поговорили, и текст я поправил, действительно, правильней описать именно как опциональное поле. Сам контракт был приведен просто чтобы описать ожидаемую структуру объекта. Причем тут ваши высказывания о том, что объекты это не просто структуры (C++ вот начал очень сильно возмущаться) мне неведомо. Понятное дело, что есть не только JSON, но любые другие сериализаторы с поддержкой опциональных полей могут вести себя ровно так же, тут, как вы верно заметили, нужна валидация. И вариантов тут два: используется готовая библиотека для валидации (хотя кто-то же ее ранее написал), валидация пишется вручную, или если бы было написано "валидируйте входящие данные", то вопроса бы у вас не возникло? Вот в случае написания проверок вручную и стоит знать о такой особенности поведения. И да, это именно нюанс языка, из которого такое поведение становится возможным. Какие возможности дает наличие undefined, мне, правда, неясно.

Upd: Ах, погодите, в тексте же есть указание на то, что потребуются дополнительные проверки. Или это не валидация?

Поздравляю, вы только что запретили использовать 0 в качестве константы t. Слабая типизация к вашему утверждению не имеет никакого отношения, она имеет отношение к неявному приведению типов, как пример - обычное ==, когда 1 == '1' возвращает true. Обращение к неинициализированной переменной либо является ошибкой (бросается исключение), либо является неопределенным поведением (undefined - как раз вариант оного). Чем меньше UB, тем проще писать надежные программы.

Мой комментарий ниже, вроде как, дополняет предыдущий. Через объявление типа через двоеточие да, будет ругаться. Если же привести к типу через as - не будет, так что даже тут TS не спасет в 100% случаев, не говоря уже о том, что только что десериализованный объект имеет тип any, который приводится к чему угодно, так что дополнительных проверок не избежать. Такое чувство, что вы пытаетесь найти огрехи в коде, который лишь является упрощенной иллюстрацией возможного развития событий. Думаю, если бы я описал еще более подробно, вы бы сказали, что воды столько, что читать вообще невозможно. Что касается stringify+parse, то undefined-поля будут просто удалены, про Vue 2 я имел ввиду всякие Vuex или computed. computed просто не заметит появление отсутствовашего свойства в объекте, даже если он отслеживаемый.

Все верно, поэтому так и написал: "Нам остается лишь помнить об этих особенностях при написании кода". Утверждение о том, что было бы лучше иначе, не противоречит тому, что есть так, как есть, и надо уметь с этим жить.

Почему не укладывается? Можно подробней?

Как-то упустил из виду, что исключения в JS были не сразу.

С точки зрения TS - только в одну сторону, а с точки зрения JS - я этот вариант (с проверкой наличия ключа) как единственный способ проверить и привел в тексте публикации, но, хорошо, аргумент принят. Статью поправлю.

Upd: ради интереса проверил, если использовать as, то TS не ругается:

const example2 = { a: 1 } as { a: number; b: string | undefined };

Если хотели сказать, что при описании типа как {a: number; b: string | undefined } нельзя задать переменной значение { a: 1 }, то стоило так и написать. И все равно, мы упираемся в TypeScript, о котором речи не идет.

Information

Rating
Does not participate
Registered
Activity