All streams
Search
Write a publication
Pull to refresh
68
0
Владимир @Googolplex

Software engineer

Send message
Ок, неправильно сформулировал. Можно, но это нужно делать только в крайних случаях. Go рассчитан на работу при включённом GC, и никаких средств (естественно, кроме аналогов malloc/free) для работы с памятью не предусмотрено, и, естестенно, подавляющее большинство библиотек полагается на GC.
Я не говорю, что это плохо — я сам программирую на Java, а мой любимый язык — Scala, но просто в Rust можно и нужно жить без GC, и это совершенно не трудно, а в Go — практически невозможно. Я только это и хотел подчеркнуть.
Или вот, например, шедулинг. В Go всегда применяется модель n:m, и вы не можете контролировать, какой поток ОС какой горутине принадлежит. А в расте у вас есть выбор (как раз с 0.9 появился) — вы можете выбрать libgreen и получить шедулинг легковесных потоков повер потоков ОС и соответствующее IO, либо вы можете подключить libnative и получить стандартные потоки операционной системы (также с соответствующим IO). И этот выбор может быть достаточно важным, например, в реалтайм- или эмбеддед-системах.
Если сборку мусора в Go отключить полностью (как и в D, например), мы получим тонну нерабочих библиотек. А в Rust изначально идиоматично написание кода, который не использует GC, и, например, вся стандартная библиотека там от сборки мусора не зависит. Если сторонние качественные библиотеки пишутся без сборщика мусора — а именно так и происходит, и будет происходить дальше, скорее всего, — то при создании уже конечных программ у вас будет выбор, использовать GC или нет, и при отказе от неё ничего не отвалится.

А насчёт разделяемых библиотек — это как раз очень важный пункт, из-за которого ниши Rust и Go пересекаются весьма условно. На Go вы не сможете написать даже плагины к своему приложению никак, кроме как через IPC, что не всегда удобно и даже возможно. Плюс из-за этого же библиотеки на Go вы не сможете нормально подключать к программам на других языках, опять же, без использования средств IPC. Я не говорю, что это безусловно плохо — с точки зрения архитектуры это может быть даже и хорошо, потому что поощряет написание слабо связанного кода, но, тем не менее, из-за таких вещей области применения языков достаточно различны.
Нет. Go — это язык с обязательной сборкой мусора, он не может использоваться в сильно низкоуровневых приложениях. Rust может, потому что там сборка мусора опциональна. Плюс у Go весьма хреновая встраиваемость в другие приложения (и поддержка модульности тоже). О чём речь, Go до сих пор не может генерировать нормальные разделяемые библиотеки. А Rust с самого начала одной из целей имел интероперабельность с C. Растовый FFI — один из лучших FFiев, которые я видел.
Да, раст с каждой новой версией становится всё стабильнее и удобнее в использовании. Хоть там и есть много довольно неоднозначных решений, мало библиотек и нет пока нормальной сборочной инфраструктуры, всё равно у него, на мой взгляд, большой потенциал. Он попадает, фактически, в незанятую нишу высокопроизводительных высокоуровневых языков, где сейчас только C++ и есть. Ну может D ещё.
gksudo -k gedit /usr/share/maven/conf/settings.xml

Так нельзя делать. Вы редактируете файл, не предназначенный для изменения сразу по нескольким причинам:
  1. это глобальные дефолтные настройки мавена, которые не должны меняться;
  2. этот файл под управлением менеджера пакетов — при следующем апдейте мавена файл либо перезапишется, либо будет какой-нибудь конфликт, либо ещё что.

Правильный способ — использовать локальный для юзера settings.xml, обычно — ~/.m2/settings.xml:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                        http://maven.apache.org/xsd/settings-1.0.0.xsd">
...
    <profiles>
        <profile>
            <id>RAMBuild</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <target.directory>/tmp/maven/${project.groupId}.${project.artifactId}/target</target.directory>
            </properties>
        </profile>
    </profiles>
...
</settings>

Мда. Очень странно, что в CodeCogs ширина выходного изображения фиксирована. Длинные формулы выглядят уныло :(
С формальной точки зрения вы правы. В этих определениях не указываются области определения переменных, а значит, по идее, они могуть быть абсолютно любыми, хоть комплексными — и в этом случае утверждения теряют смысл вообще.

Однако, чтобы не захламлять запись, обычно подразумеваются вполне конкретные области определения переменных, общепринятые в данной области математики. Например, в матанализе принято считать, что индексы вроде n, N, k, p всегда только натуральные, а значения x_n или \varepsilon — вещественные. Поэтому формула вроде
image
на самом деле эквивалентна такой:
image
Но, естественно, так никто не пишет.
Первое, что мне пришло в голову, когда я увидел скриншоты — это ranger:
image
VB, например, с кроссплатформенностью не сильно дружит. F# тоже не далеко ушел. Да даже С++ есть далеко не для всех архитектур и операционок. Тут спорить можно до хрипоты, но нам это ничего не даст.

И, тем не менее, программу, написанную на F# или, например, на VB.NET можно запустить как под виндой (x86_64), так и на мобильнике (ARM). А если ещё вспомнить Mono, который работает на линуксе, и вспомнить количество платформ, поддерживаемых линуксом… Для C++ это справедливо в ещё большей степени. И дело здесь не в «степени» кроссплатформенности, а вообще в её наличии или, хотя бы, потенциальной возможности. Практически любой широкоиспользуемый язык высокого уровня является, по крайней мере, потенциально кроссплатформенным. Ассемблер — нет, просто в силу самого его определения.
Отличное замечание. То есть мы сравниваем не языки, а наличие/отсутствие библиотек? Тут конечно, наличие библиотеки всегда лучше ее отсутствия. При этом, «почемуто», априори считается что программист на ассемблере не должен пользоваться сторонними библиотеками вообще, а Сшник — только и и обязан что их применять. В статье и говорится, что в силу неизвестных мне причин, библиотеки используют крайне спорные методы передачи параметров, которые, в дополнении ко всему, еще и не очень удобны при использовании асемблера.

Вы заговорили о том, что низкоуровневые программы на C не портируемы. С чем я согласился, потому что так или иначе любая программа сводится к взаимодействию с железом, и код, который обращается к тем или иным железным вещам (вроде тех же портов) обязательно будет платформозависимым. Если что-то подобное нужно будет делать из языков высокого уровня, то без библиотек просто не обойтись — низкоуровневую кухню приходится абстрагировать. И это не есть плохо — потому что зачастую можно абстрагироваться так, что код станет кроссплатформенным, и отличаться на разных платформах будут только отдельные кусочки, непосредственно связанные конкретной платформой. А вот для ассемблера так не сделаешь, просто потому что ассемблер привязан к платформе. Ну как вы на ассемблере напишите абстрактную библиотеку для работы, скажем, с портами, если вы её скомпилировать сможете только для одной архитектуры? Заметьте также, я говорил про низкоуровневые системные библиотеки, не про прикладные.

Вообще же библиотеки и языки используют соглашение, которое сложилось исторически и достаточно эффективно с машинной точки зрения. Да, оно может быть неудобно, если код на ассемблере писать руками, но писать на ассемблере прикладные программы не имеет смысла (см. мой самый первый комментарий — кроссплатформенность, простота разработки, поддерживаемость и т.д.), поэтому никто не заботится о том, чтобы из ассемблера было удобно вызывать сторонний код. Потребителем ассемблера (фактически, машинного кода) является компьютер, и ему наплевать сколько параметров запихивать в стек. Компилятор позаботиться о генерации корректного кода для передачи параметров.

Почему если человеку нравится программировать на ассемблере, то это обзательно должен быть «красноглазый ретроград»? Я за любые языки программирования. Но это не повод плодить и оправдывать «корявые» решения что на С, что на ассемблере, что на любой другом языке.

I see your point. Сорри.

Я всего лишь говорю, что преждевременная типизация, равно как и преждевременная оптимизация — это больше недостаток, чем преимущество. И дело не только в удобстве пользователя (как например, странность, почему в результате умножения переменной (с гарантированно вещественным значением) на целое значение «куда-то» пропадает дробная часть, это из SQL), но и в эффективности программы. Когда для вычисления A * B может быть использована и целочисленная (быстрая), так и вещественная (медленная) арифметика, в зависимости от фактических значений этих переменных на момент вычисления.

Извините, но то, что вы описали, есть динамическая типизация. SQL является языком с динамической слабой (тут могу ошибаться) типизацией. В языках со строгой типизацией вы такого никогда не сможете получить. Из ваших слов я вижу, что вы — сторонник динамической типизации, даже если и сами этого не осознаёте. Ну что же, ваше право. Это действительно очень холиварная тема, и я не хочу начинать здесь спор на эту тему.

А что тут демонстрировать? При преобразовании значения (например для поиска) — игнорируем все символы, кроме цифр. При этому исходное значение в строком виде не изменяем. В чем сложность то?

Сложность в том, что простым «игнорированием» всех символов, кроме цифр, вы не получите число. Мне показалось, что это должно быть очевидным вам, как любителю ассемблера. "+7-909-78956234" — это строка, скорее всего, массив байт в кодировке ASCII. Игнорированием отдельных символов вы получите тоже строку, а не число. Чтобы получить число, вам придётся совершить какое-то количество операций умножения на степени десятки. Именно на это я и хотел указать. Просто так, забесплатно, вы в принципе не сможете рассматривать произвольные данные в произвольном виде. Типизация — это фундаментальное свойство представления данных в компьютере, и вы от этого никуда не денетесь.

Кстати, я ещё подумал насчёт предложенной вами концепции передачи параметров. Где будет находиться память под вашу структуру? На стеке? Это ничем не будет отличаться от уже существующих calling conventions. Ну за исключением битовой маски, но я, если честно, совершенно не вижу в ней смысла. В куче? Это будет, мягко говоря, дорого. Операции работы с кучей в современных ОС дорогостоящи, потому что ОС должны бороться с фрагментацией, и выделение куска памяти в куче может занять довольно много времени. В памяти для статических переменных? А что делать с рекурсивными вызовами и с многопоточностью? Нет, стек является совершенно естественным способом хранения и передачи параметров в подпрограммы, и в любом соглашении о вызовах на любом процессоре, даже если это соглашение включает в себя передачу параметров через регистры, так или иначе используется стек. См. здесь.
Огромное вам спасибо!
Оказывается, подчёркивания под рукописный текст — это так просто! Когда делал титульные листы для курсовой и диплома, от незнания перебирал кучу костылей и так в итоге отказался от этого :(
Можно тот же самый вопрос задать про С++, VB, F#, Haskel.

Нет, нельзя. Все эти языки так или иначе позволяют писать кроссплатформенные программы с высокой скоростью разработки и достаточным уровнем корректности.
хотя тот же Python, или Java «портируемы» еще как

Не понимаю вашего сарказма. Python и Java являются кроссплатформенными языками, и программы на них именно что портируемы.
пока дело не касается низкоуровнего программирования

Заметьте, я про это сказал в своём комментарии. Если необходимо писать программу на таком низком уровне, что нужно учитывать способ работы с портами ввода-вывода, то ассемблер будет нужен. Хотя, на мой взгляд, здесь и C можно обойтись, потому что, скорее всего, под ту архитектуру, которая вам нужна, уже кто-нибудь написал соответствующую обёртку. Либо, если это не так и если понадобится работать с этой архитектурой долго, можно стать первопроходцем и что-то подобное написать самостоятельно.
Ассемблер проигрывает в «портируемости» между архитектурами, но не между ОС.

Вы хоть раз программировали на ассемблере под ОС, отличной от Windows? Я да. Разница в программировании на чистом ассемблере, без библиотек вроде libc, огромна. По Windows вам придётся вызывать функции Windows API. Под линуксом вам придётся дёргать системные вызовы с помощью int $0x80. Естественно, набор этих функций абсолютно разный. Работа с памятью тоже немного другая — форматы бинарников разные. Поэтому если вы хотите перенести программу из одной ОС в другую, даже если они работают на одной архитектуре, вам придётся её переписывать.
Насчет SSSE. Там нет такого уж кошмара, вопрос лишь в подготовке данных.

Я не нашёл точных данных, но если судить по толстенному мануалу от Intel, то вместе со всеми расширениями (MMX, MMX+, EMMX, 3DNow, 3DNow+, SSE, SSE2, SSE3, SSSE3, SSE4, FMA) я думаю что не сильно ошибусь, если скажу, что их около полутора тысяч. Вы хотите сказать, что сможете их применять правильно и тогда, когда нужно? Вы очень круты, если так.
Сможете сами сделать — отлично, не сможете, нестрашно, есть, например, Фортран.

Вы же против высокоуровневых языков, нет?
А про «низкоуровневую модель памяти» я не понял. Что это?

Это то, как процессор работает с памятью.
Так типизация и решает задачу валидации данных.

Нет. Типизация может помочь при валидации, но основная задача типизации — это обеспечение корректности программы, то, что вы описали как «быть уверенным, что вы умножаете вещественное число, а не строку». Это не является валидацией. Безусловно, наличие типизации является колоссальным плюсом с точки зрения компилятора. И да, типизация может внести сложности для программиста — просто потому, что программист не сможет скомпилировать программу, которая содержит ошибки типов. Статическая или динамическая типизация — весьма холиварная тема. Лично я считаю, что статическая типизация есть благо, по разным причинам — начиная от обеспечения минимальной корректности программы и до упрощения создания мощных IDE. Однако типизация ни в коем случае не составляет сложности для пользователя программы. Неужели вы думаете, что если нет типизации, пользователь автоматически сможет вводить всё, что захочет, в том формате, в котором захочет, и ваша программа это автоматически проглотит? Пользователю глубоко наплевать, на чём написана программа, главное, что её можно запустить и поработать с ней.
Как пример, у нас есть некий телефонный справочник. Номер телефон это что? Целое число или строка? При отсутствии типизации мы может обрабатывать его и как число (для поиска и сравнения так будет быстрее) и как строку — для хранения номера в том виде, в каком его ввел пользователь.

Если честно, я буду очень рад, если вы продемонстрируете эту магию. Лично я не представляю, как с помощью ассемблера (да и не только ассемблера, в принципе — даже слабая типизация как в JS имеет свои границы) можно произвольные данные автоматически рассматривать в произвольном виде. Пожалуйста, продемонстрируйте, как вы будете обрабатывать +7-909-78956234 и как число, и как строку. Желательно, на вашем любимом ассемблере.
Вы можете объяснить, пожалуйста, зачем нужно программирование на ассемблере в современных десктопных или мобильных операционных системах? За исключением вырожденных случаев вроде глубоко системных платформеннозависимых вещей, кодеков и супербыстрых вычислений (хотя и здесь можно поспорить насчёт необходимости ассемблера), ну и, может быть, обучения?

Гораздо важнее скорость разработки, простота поддержки и портируемость приложений. И по всем этим параметрам ассемблер очень сильно проигрывает, особенно в том, что касается портируемости.

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

А что насчёт многопоточности? В языках высокого уровня очень много абстракций, облегачющих написание concurrent-кода, вроде акторов и STM. Лично мне довольно слабо представляется, как организовывать сложный многопоточный код в отсутствии нормальной высокоуровневой модели памяти. Акторы на ассемблере? Хм…

Ваше отношение к типизации тоже не очень понятно. Как мне кажется, вы смешиваете понятия типизации и валидации:
То есть очевидное нарушение системного подхода – как будто разработчики языков высокого уровня рассматривали свои системы без учета взаимодействия с внешним миром. В итоге, программируя на типизированном языке разработчик должен предсматривать все возможные виды «неправильных» входных данных, и искать способы обхода неопределенностей. И вот тут на сцену выходят монструозные системы поддержки регулярных выражений, обработки исключительных ситуаций, сигнатуры методов/процедур для разных типов значений и прочая прочая генерация костылей.

Что значит — предусматривать все возможные виды «неправильных» входных данных? Вы имеете в виду валидацию, то есть, проверку содержимого, вроде того, представляет ли строка адрес электронной почты? Но это понятие не тождественно типизации. Более того, наоборот, типизация помогает валидации данных, потому что типизация ограничивает множество значений конкретной переменной. Валидация данных необходима в любом языке, независимо от системы типов.

Я при этом не касаюсь разработки для встраиваемых устройств. Там использование ассемблера полностью оправдано. Но там и нет описанных вами «проблем», или, по крайней мере, они себя не проявляют.
Интересная статья, спасибо.

Когда человек пишет код, для него естественнее двигаться снизу вверх — от более низкоуровневых компонент к более высокоуровневым.

Спорное утверждение. Проектирование «сверху вниз» тоже имеет место, и, как мне кажется, более плодотворно. Сначала продумываются интерфейсы, и потом уже делается их реализация, с постепенным увеличением количества деталей. Особенно этот подход справедлив в функциональных языках вроде Haskell, но и в объектно-ориентированных он тоже применим.
Прелюдия (Prelude) — стандартная библиотека самых необходимых функций, определяется стандартом Haskell 98.

Хоть это, безусловно, и правда, но хочу заметить, что Haskell 98 уже устарел. Текущая версия стандарта — Haskell 2010.
Далее, вы не сортируете углы относительно минимальной точки. Вы сортируете углы относительно 0+j0, просто отняв угол минимальной точки и взяв абсолютное значение.

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

Что такое «сортировка углов относительно минимальной точки» также не совсем понятно. Для меня эта фраза означает «сортировка значений углов по метрике в R относительно угла минимальной точки», и это именно то, что я написал.

Но он понятен, но не использует по всей видимости только изначальные языковые вещи. (Я не знаю Питон).
sortBy — это скорее уже библиотечная функция, как и тип List, даже если они из коробки.

Почему это важно? Потому что я показал разбор только одной строки, которая удачно, только с сортировкой связана. На джее таким же образом можно сделать всё.

Я опять не понял, что вы хотели сказать. Вы имеете в виду, что те глаголы, которые использу.ются в примере, встроены в язык, а типы и методы вроде List и sortBy являются частью стандартной библиотеки? А какая разница? Из Scala стандартную библиотеку убрать нельзя в принципе, поэтому классы коллекций вполне можно считать частью языка как платформы. Я не вижу существенной разницы этого с наличием встроенного в язык функционала, разве что последнее менее гибко.

o. применяется для разных случаев.
Есть такой очень важный принцип, особенно в обучении. Называется «принцип наименьшего удивления». Когда я вижу sortBy, я могу с достаточной долей уверенности предполагать, что это какой-то вариант сортировки. Приставка By также намекает, что мы будем указывать то, с помощью чего нужно сортировать. То же самое с фазой комплексного числа: minimal.phase, особенно в контексте того, что minimal имеет тип Complex, однозначно говорит, что мы хотим взять значение фазы. 12 o., к сожалению, об этом говорит чуть менее, чем никак. Особенно если учесть, что, судя по всему, 13 o. и 11 o. будут делать что-то совершенно другое, если это вообще будут корректные выражения.

В этом, собственно, и ответ на ваш вопрос. Вы не только утверждаете, что это очевидно и легко (с этим, в принципе, я могу согласиться — для кого-то продвинутая теория категорий или тот же китайский легки и понятны, всё-таки всё в мире относительно), но вы также утверждаете, что это проще и понятнее, чем идентификаторы, приближенные к человеческому пониманию кода. Я так полагаю, что именно с этой вашей позицией здесь и не согласны.
Я полагаю, дело в том, что, например (если я правильно понял ваше объяснение) такой код:

def order(numbers: List[Complex]): List[Complex] = {
  val minimal = numbers.min
  numbers.sortBy(number => abs(number.phase - minimal.phase))
}


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

А код, который вы только что разобрали, непонятен не только непосвящённым (вот откуда можно понять, что 12 o . — это взятие фазы комплексного числа, а?), но я боюсь, и начинающим изучать J тоже.
«Подъезжая к сией станцыи и глядя на природу в окно, у меня слетела шляпа.»
Извините, не удержался. Глаз режет.
Вот здесь написано:
Since the $GOPATH variable can be a list, the rest of this document will use $GOPATH to mean the first element unless otherwise specified.


И там же:
It is useful to have two GOPATH entries. One for a location for 3rd party goinstalled packages, and the second for your own projects. List the 3rd party GOPATH first, so that goinstall will use it as a default destination.


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

Ну и, в конце концов, всегда можно провести эксперимент.
Если я не ошибаюсь, то в первый. Надо посмотреть на сайте Go, там это есть.

Information

Rating
Does not participate
Location
Santa Clara, California, США
Date of birth
Registered
Activity