• +1

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

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • 0
    стоимость выполнения тех или иных операций (выраженная в деньгах)

    В идеале об этом должен компилятор думать. Он должен это измерять, компилировать, оптимизируя именно эту стоимость, выдавать вам советы в виде предупреждений и т. д. В светлом будущем, наверно, так и будет :-)

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +2
    Нет, предполагалась логика именно плавучки и не иначе.

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

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +1
    Автор(комментария) предлагает взять из копеек сделать рубли в рамках целых чисел

    Где я это предлагал? Я предлагал не работать с голыми числами вообще, ни с целыми, ни с дробными. Их надо видеть только в точках взаимодействия с внешними системами. А там уже тип зависит от того, который навязан внешней системой. Я ничего не говорил ни про целые, ни про дробные, ни про пару. Объект класса Amount может всё внутри переводить в ваши любимые вэи, может использовать дробные числа, может хранить пару, это без разницы. В этом суть абстракции. Завтра точности вэев станет недостаточно, поделят их ещё в тысячу раз и что тогда? Если у вас код абстрагирован от представления, поменять придётся только один класс.

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +2
    Если вам это нравиться — так и пишите, но про «должны» — забудьте.

    Во всех языках мира придуманы разделители групп разрядов. Где-то апостроф сверху, где-то запятая снизу, где-то пробел. Это сделали не потому что кому-то нравится, а потому что это снижает вероятность ошибки. Подчерки лишь пример синтаксиса, он может быть любым, но вероятность ошибки должен снижать.


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


    Жава не поддерживает, как и 99% языков. Что дальше?

    Яркий пример, когда хочется что-то сказать, а сказать нечего. Перегрузку операторов поддерживают многие языки. Из популярных больше поддерживают, чем не поддерживают. Да и суть не в этом, можно и .subtract писать, это не сильно хуже.


    Язык он про сложение чиселок. Так везде.

    Какое-то у вас примитивное представление о программировании. Либо вы на ассемблере всю жизнь пишете, тогда простительно.


    Такого компилятора у жавы нет, как и у 99% языков. Что же с этим поделать? Откуда он должен взяться тут?

    Джавовый JIT (Hotspot C2) вполне способен на такие оптимизации. Я полагаю, Clang с кодом на C++ легко разделается тоже. Тут вполне тривиальная цепочка оптимизаций инлайнинга, эскейп-анализа и констант-фолдинга. Это всё в теории компиляции известно десятилетиями. Не знаю, что там в солидити, но учитывая, какие деньги крутятся в этериуме, хорошего компиляторщика нанять не должно быть большой проблемой.


    Смысл последнего абзаца в том, что этериум = джаваскрипт и ничего с этим не поделаешь? Я думаю, в основу платформы никакая типизация не заложена и на ней вполне можно сделать нормальный язык, компилируемый в этериум. Либо он уже существует, просто автор этой статьи не умеет им пользоваться.

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +1

    1 ether получше, чем восемнадцать нулей, хотя скрывается тот факт, что оно выражено в веях. Возможно, это ничего, если все привыкли считать, что всё и всегда выражено в веях. Но оно опять же явно не так. В коде автора, например, есть tokensPerOneEther = 5000, а вовсе не цена одного токена в веях. Очевидно, что не всегда удобно работать с веями, надо с разными единицами уметь.

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +17

    Смотрю с точки зрения обычного программиста. В ваших смартконтрактах реально принято код загружать такими константами вида 1000000000000000000? Ведь это какое-то наивное детское программирование, хоть и называется громким словом solidity. Это неправильно на кучу слоёв.


    Слой 1. Можно легко пропустить где-нибудь нолик или неправильно их сосчитать и неправильно понять код. Язык должен позволять писать 1_000_000_000_000_000_000. Если позволяет, программисты должны этим пользоваться.


    Слой 2. Это всё равно неправильно, потому что вероятность ошибки с пропуском нолика существует до сих пор. Должна существовать предопределённая именованная константа вроде WEI_PER_ETHER = 1_000_000_000_000_000_000, и в коде должна использоваться только она. Тогда станет понятнее, что происходит и вероятность ошибки ещё снизится.


    Слой 3. И это всё равно неправильно, потому что можно неправильно сделать вычисления. Например, умножить там, где надо разделить, передав не 10-18, а 10+18 попугаев. Нужны предопределённые функции или макросы с понятными именами вроде convertWeiToEther(weiAmount) и convertEtherToWei(etherAmount).


    Слой 4. И это всё равно неправильно, потому что можно по ошибке забыть вызвать макрос. Должна быть объектная типизированная модель, исключающая возможность присваивания неправильного значения. Что-нибудь вроде WEI.amount(uint256 value) возвращает объект типа Amount, и чтобы получить сумму в эфире, надо вызвать WEI.amount(value).toEther(). При этом не следует использовать сырые значения в числах слишком часто, только в исключительных случаях вроде окончательного обмена данными с внешним источником. В идеале это должно быть спрятано в методах родительских контрактов и всякие msg.value уже должны иметь тип Amount и писать надо msg.value.subtract(MY_TOKEN.amount(tokens)), где константа Currency MY_TOKEN = createStableCurrency(Ether.amount(1/5000)). Я придерживаюсь синтаксиса джавы, но это необязательно. Язык может и перегрузку операторов поддерживать, тогда можно писать msg.value - MY_TOKEN.amount(tokens), но при этом компиляция не пролезет, если попытаетесь эфир вычесть из токенов или сложить токены с веями.


    Пока всё выглядит так, что детям дали бомбой поиграться. И не надо рассказывать мне про стоимость исполнения на Etherium VM. Хороший оптимизирующий компилятор можно выкинуть все эти слои абстракций, сгенерировав точно такой же конечный код.

    Смарт контракты Ethereum: пишем простой контракт для ICO
  • +1

    Нет. Тут сперва создаётся стрим из одного элемента и флэтмэпится на миллион. В этом и суть.

    Причуды Stream API
  • +5

    Если что, картинки для «причуд» я надёргал с интернета вечером перед докладом, потому что мне показалось, что презентация скучновата. Не уверен, что это было правильное решение.

    Причуды Stream API
  • 0

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

    Готовимся к Java 9. Обзор самых интересных улучшений
  • 0

    Думаю, не будет Collection literals. По крайней мере, не в ближайшие годы.

    Готовимся к Java 9. Обзор самых интересных улучшений
  • 0

    А если мутабельный список, потокобезопасный он или нет? А добавление в начало или в середину дешёвое или нет? Реализаций списков много. А с Set и Map ещё хуже. Сохраняет ли порядок, сортирует ли ключи. Например, в JavaScript объекты сохраняют порядок вставки, а это дополнительные ненужные накладные расходы в 99% случаев. Сериализуемость, потокобезопасность. Можно ли в Java 9 сериализовать List.of(x) и десериализовать его потом в Java 8, получив аналог Collections.singletonList(x)? Много, много интересных вопросов влечёт такая фича. Это всё на тему того, почему 10 лет назад не сделали.


    ArrayList.of(1,2,3) обсуждался, но он перекрывает List.of(1,2,3), а это нехорошо, когда один статический метод перекрывает другой, меняя семантику. Опять же привет старому поспешному дизайнерскому решению, что статический метод можно вызывать, используя подкласс в качестве квалификатора. Напишите вы class MySuperList extends ArrayList implements List, и что будет значить MySuperList.of(1,2,3)?

    Готовимся к Java 9. Обзор самых интересных улучшений
  • 0

    forEach изящнее выглядит со ссылкой на метод. Кроме того может быть несколько быстрее, потому что не создаётся итератор.


    Я до сих пор не понимаю, почему разработчики Java решили добавить Stream API непосредственно в интерфейс коллекция?

    Ну вот любят люди всё такое fluent-fluent. Все вон трещат, чтобы им прямо в коллекцию добавили map или filter. Написать свой утилитный класс и вызывать статические методы религия не позволяет. Stream.from(veryLongCallProducingACollection).many().stream().operations() тоже смотрится не очень.


    Вообще с точки зрения разработчиков Java, стримы более базовая вещь, чем коллекции. От коллекций по факту зависит только класс Collectors, который утилитный. Остальные стримы от коллекций не зависят.

    Используйте Stream API проще (или не используйте вообще)
  • 0

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

    Готовимся к Java 9. Обзор самых интересных улучшений
  • 0

    Читайте дискуссии на эту тему в core-libs-dev. Много что мешало.

    Готовимся к Java 9. Обзор самых интересных улучшений
  • 0

    А потом программисты начнут использовать эти два метода, а пользователи начнут жаловаться, почему это у них новая версия программы падает с NoSuchMethodError. А программисты им такие, да, теперь вам каждую неделю надо обновлять JRE, чтобы пользоваться нашим софтом.

    Готовимся к Java 9. Обзор самых интересных улучшений
  • +1

    Насчёт IDE не заменяет голову, кстати, пример. IDEA предупредит, если вы напишете Arrays.asList(array).stream(). Но если у вас сложный внешний стрим и в нём встретится .map(Arrays::asList).flatMap(List::stream) вместо простого .flatMap(Arrays::stream), то тут уже не предупредит. Или про filter().findFirst().isPresent() скажет, но если вы промежуточный Optional присвоите в переменную и используете её только для isPresent, то уже увы. Может когда-нибудь и эти случаи покроем, но не стоит надеяться, что IDE вам подскажет всегда.

    Используйте Stream API проще (или не используйте вообще)
  • +4

    Готово


    Используйте Stream API проще (или не используйте вообще)
  • 0

    Собственно да. С помощью стандартного Stream API вроде красиво не решить. Моя библиотека StreamEx позволяет легко сделать такой коллектор:


    static <T> Collector<T, ?, Boolean> anyMatchOrEmpty(Predicate<T> predicate) {
        return MoreCollectors.pairing(
              MoreCollectors.filtering(predicate, MoreCollectors.first()), 
              MoreCollectors.first(),
              (filtered, nonFiltered) -> filtered.isPresent() || !nonFiltered.isPresent());
    }

    С обычным стримом он не будет короткозамкнут, но если источник обернуть в StreamEx (или если источник сразу возвращает StreamEx), то будет:


    return StreamEx.of(someStream(...)).collect(anyMatchOrEmpty(condition));
    Используйте Stream API проще (или не используйте вообще)
  • 0

    Однако он не будет короткозамкнутым, потому что в стандартном Stream API не бывает короткозамкнутых коллекторов (у меня в StreamEx они есть)

    Используйте Stream API проще (или не используйте вообще)
  • 0

    У Optional действительно есть особенность, нарушающая монадический закон: map(map(opt, F), G) ≠ map(opt, G○F) или в Java-терминах opt.map(F).map(G) != opt.map(G.compose(F)). Если F возвращает null для какого-либо значения, то в композиции G выполнится с аргументом null, а в Optional G не выполнится вообще. Пуристы в этом месте начинают плеваться. Ну и, например, соответствующий рефакторинг для Optional, который предлагает IDEA, по факту меняет семантику кода (а для Stream не меняет).

    Используйте Stream API проще (или не используйте вообще)
  • 0

    Да, я такое тоже встречал. К сожалению, автоматически предлагать склеить это в одну цепочку опасно. Может человек полагается на сайд-эффекты и ему важно, чтобы все первые операции выполнились до вторых. Классический пример:


    List<CompletableFuture<T>> futures = callables.stream()
       .map(CompletableFuture::supplyAsync).collect(toList());
    List<T> results = futures.stream()
       .map(CompletableFuture::join).collect(toList());

    Здесь если склеить в один стрим, то все фоновые задачи будут выполняться последовательно (причём этого можно не заметить, скорее всего тесты не упадут).

    Используйте Stream API проще (или не используйте вообще)
  • +1

    Не поверишь, но около половины нашлось в коде IDEA Ultimate / Android Studio :-)

    Используйте Stream API проще (или не используйте вообще)
  • 0

    Про Optional может быть. С CompletionStage не наберётся материала, его используют сильно реже.

    Используйте Stream API проще (или не используйте вообще)
  • +1

    Нет-нет, именно b->b.


    Ваш пример интересен. sort() меняет текущий список. По сути дела замена — это два выражения, List<T> sortedParams = new ArrayList(params);sortedParams.sort(...);. Это заметно оптимальнее, но можно спорить, красивее ли. Теперь, к примеру, sortedParams не заинлайнишь, к примеру.

    Используйте Stream API проще (или не используйте вообще)
  • +7

    Мне многие из них тоже казались нереальными, пока я их не увидел в реальном коде :-)

    Используйте Stream API проще (или не используйте вообще)
  • +14

    У джавы своя философия. В частности, в джаве ценится ясность кода. Наличие методов типа map прямо у коллекций не даёт явного понимания, метод ленивый или нет, будет ли промежуточная коллекция, если сделать два раза map или нет. А со стримами всё понятно. Вы можете сказать, мол, давайте скажем, что у коллекции все методы неленивы. Но если сама коллекция — это вьюшка над другой коллекцией? Скала тут как раз засорила все абстрактные интерфейсы кучей всего. Пришёл вам Traversable, вы вызываете у него map. Что вы получите, новую независимую копию или вьюшку над старой? Зависит от того, что вам на самом деле там передали, TraversableView или тупо List. По факту протекающая абстракция. Кому-то нравится такой подход, абстрагировать всё и вся, те пишут на Скале. Мне нравится, когда я лучше понимаю, что в моём коде происходит, поэтому я пишу на Джаве. Это замечательно, что есть разные языки с разной философией.

    Используйте Stream API проще (или не используйте вообще)
  • +2

    Там не очень много. Почти всё перечислено, например, здесь

    Используйте Stream API проще (или не используйте вообще)
  • 0

    "Что бы съесть такого, чтобы похудеть?"

    Как работает рекурсия – объяснение в блок-схемах и видео
  • 0

    А про штуки вроде разных имён для live-темплейтов — лучше посылать баг-репорт в youtrack.jetbrains.com.

    Kotlin: опыт боевого применения
  • +3

    Вот, трезвый взгляд на ситуацию. Я тоже постоянно натыкаюсь на недоработки и баги тулинга. Причём довольно сложно делать какую-то фичу IDE так, чтобы она волшебным образом заработала и для Джавы, и для Котлина сразу. Иногда что-то можно объединить, но в большинстве случаев это двойная работа для авторов IDE. В джаве больше всяких инспекцией и квик-фиксов, в том числе ориентированных не на фичи языка, а на библиотеки. Логично ожидать, что при использовании тех же библиотек из Котлина вы получите аналогичную поддержку. Но так бывает увы не всегда.

    Kotlin: опыт боевого применения
  • +1

    Я в среднем иду пешком до работы 20 минут. Минут 45, если сына в садик по пути отвожу. Житель Академгородка.

    Путешествие за бугор и обратно: как не надо устраиваться работать за рубежом
  • 0

    Делай доклад на конфу. Кишочки норм.

    Как JVM аллоцирует объекты?
  • 0

    Судя по посту автор обсмотрелся видосов Шипилёши. Вот когда твои видосы будут такие же популярные, тогда и перестанут ;-)

    Как JVM аллоцирует объекты?
  • 0

    Про IDEA и 100% CPU — с большой вероятностью какая-то бага, специфичная для конфигурации, окружения, технологий, используемых в проекте и т. д. 20-30 секунд анализировать код после внесения правок — это ненормально. Если есть время поразбираться, сделайте баг-репорт по инструкции. Спасибо.


    Ну и можно, конечно, heap подкрутить, как sotnikdv пишет выше.

    Найдена новая версия программы. Устанавливаем?
  • 0

    Когда я просто прохожу мимо этого места мне как-то наплевать, есть там табуляция или нет, я просто мимо проходил. Как это может действительно отвлекать?

    Notepad++: проверка кода пять лет спустя