Комментарии 50
Rust идёт с идеей «как избавиться от GC и не страдать с ручным управлением памятью». А с чем идёт nim?
В Rust ещё чудесная идея безопасного распараллеливания задач. А у Nim идея несколько другая — зачем писать на скриптовых языках то что можно скомпилить в очень быстрый код? Nim может помочь переписать горы питоньего кода из системных утилит линукса и тем самым повысить общую производительность системы + низкий порог входа.
Да, тоже появилось ощущение «ниши Go». Даёшь сравнение nim и go!
Вам не кажется что это попахивает «предварительной оптимизацией»? Те утилиты, для которых важна производительность уже написаны на c++ и nim там не особо нужен.
Как пример — исследование с большим объёмом данных.
А в чём будет заключаться избыточность оптимизации, если время написания кода не увеличивается, а время выполнения — сокращается, увеличивая производительность процесса разработки в целом?
Исследования с большими данными часто упараются в потолок по памяти. А там GC уже убивает производительность полностью. Но да, много случаев и когда памяти хватает с запасом.
Всё же на мой субъективный взгляд, на расте код получается более красивый и визуально понятный. Нимовские лямбды в реализации подсчета слов меня вообще повергли в уныние — черезмерно громоздки. Вцелом нимовский код выглядит угловатым и за него всё время цепляется взгляд. И это при том, что раст это скорее системный язык. Это что касается эстетической, а значит субъективной стороны. В остальном же, не совсем понятно, что с чем сравнивается, ведь языки похоже создавались для разных целей, а подобные тесты в плане производительности не дают никаких репрезентативных результатов.
Но в любом случае, больше спасибо за статью, до этого момента не смотрел на ним, теперь обязательно посмотрю на него поближе.
У меня обратный случай. Я Питонист и синтаксис Nim'а мне очень приятен(за исключением лямбд, они действительно выглядят дико), а синтаксис Rust'а пугает.
Как питонист скажу что к синтаксису Rust быстро привыкаешь. Тем более, что в нем нет никаких лишних символов, как в С++ или Rust. Точка с запятой в нем играет семантическую роль, а круглые скобки только там, где они действительно нужны.
??? "… к синтаксису Rust быстро привыкаешь… в нем нет никаких лишних символов, как в… Rust"
Это опечатка. Должно было быть «как в С++ или Javascript». :)
Что-то все как-то обходят стороной, в обсуждениях Nim, такой не маловажный момент, как команда разработчиков языка.
За Rust стоит хорошая команда. А что там с Nim?
Вы тоже, в статье, скромно умолчали про это.
Т.к. автор оригинальной статьи причислил «strong core team» к сильным сторонам Rust, могу предположить, что Nim этим не отличается. В контрибьютерах Nim самым активным (что не удивительно) является сам автор языка Andreas Rumpf.
Было бы интересно сравнение с D увидеть.
Вот фрагмент из книги «The D Programming Language» выполняющий подсчет слов. Как по мне гораздо нагляднее и проще чем на Rust и Nim. Обращаю внимание, что код не полностью идентичен решениям из статьи. Просто как пример взял.

import std.stdio, std.string; 

void main() { 
	uint[string] dictionary; 
	foreach (line; stdin.byLine()) { 
	// Break sentence into words 
	// Add each word in the sentence to the vocabulary 
	foreach (word; splitter(strip(line))) { 
		if (word in dictionary) continue; // Nothing to do 
		auto newlD = dictionary.length; 
		dictionary[word] = newlD; 
		writeln(newlD, '\t', word);
		}
	}
}

Но ведь это язык из другой весовой группы. Он выполняется в виртуальной машине.
поддерживаю насчет D — очень приятный язык (субъективно конечно)
Мне он тоже кажется куда более лаконичным чем Rust. Я удивлен где люди в Rust находят какую-то красоту, хотя решения на нем получаются значительно длиннее чем на D, при том что возможности языков примерно одинаковые. Иллюстрация этому — программа подсчета слов.

Чтобы предотвратить развитие темы про не отключаемый GC в D уточню, что он в нем уже отключаемый.
Для этого наверно нужно действительно подождать появления Rust-style кода. Можно попробовать не разворачивать итераторы в for — не будет такого давления вложенностями. Rust действительно обеспечивает «нулевую стоимость абстракций» и их не стоит бояться. Но для всего этого нужен опыт, с которым пока туго — язык молодой и до сих пор сильно менявшийся.

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

На днях исправлял в вики примеры кода 2013-го года на актуальные. Местами Rust стал значительно компактней.
Отключаемый-не отключаемый — это не так интересно. В Nim он тоже «отключаемый» и можно при желании пользоваться голыми указателями.

Сила Rust не в отсутствии GC как таковом, а в отсутствии GC и безопасности работы с памятью при этом.
Ничего личного, но код в статье я бы примером для подражания не назвал.
>Сила Rust не в отсутствии GC как таковом, а в отсутствии GC и безопасности работы с памятью при этом.
К сожалению обратная сторона этой силы чрезвычайная сложность изучения языка. В итоге вероятность написания говнокода сильно возрастает из-за неправильно понимания концепций работы со всей этой память.

Для кучи задач GC это добро т.к. позволяет больше думать про архитектуру приложения, чем про указатели и память.
Ну вот для остальных был создан Rust. Как альтернатива C/C++ в первую очередь.
Программа подсчёта слов на Rust делает гораздо больше чем вышеприведённый пример на D (о чём автор того комментария, кстати, сказал). Я думаю, что аналогичная по функциональности программа на D будет аналогична по длине.

К тому же код в статье можно сделать почище, например, избавиться от лишних as Box<Reader/Writer>.
Rust вроде тоже не страшен ;) Чуток многословнее, но того требует обработка ошибок в отсутствие исключений.

use std::collections::HashMap;
use std::io::{stdin, BufRead, Result};

fn main() {
    word_count().unwrap();
}

fn word_count() -> Result<()> {
    let mut dictionary = HashMap::new();
    let stdin = stdin();
    for line in stdin.lock().lines() {
        for word in try!(line).trim().split(' ') {
            let new_len = dictionary.len();
            if dictionary.insert(word.to_owned(), new_len).is_none() {
                println!("{}\t{}", new_len, word);
            }
        }
    }
    Ok( () )
}
Обычно Rust более многословен только потому, что не позволяет закрыть глаза на необходимость обработки ошибок. Но как по мне, это плюс, а не минус: лучше учится делать все по уму, чем выпендриватся однострочниками.

Конечно, посчитать что-то в пару нажатий клавишь как в ipython не получится. Но он для этого и не предназначался.
Может, но есть нюансы. Цитата из доки: «Nim supports the generation of DLLs. However, there must be only one instance of the GC per process/address space. This instance is contained in nimrtl.dll. This means that every generated Nim DLL depends on nimrtl.dll. Note: Currently the creation of nimrtl.dll with thread support has never been tested and is unlikely to work!»
Пара вопросов про nim.
1. Есть ли в нем pattern matching? В документации я нашел только примитивное использование case и множественное присваивание в let. Есть ли полноценный механизм?
2. Rust мне очень нравится тем, что функция возвращает значение последнего выражения и не надо писать return или использовать другие хитрые механизмы. В nim в документации описаны два механизма — оператор return и приваивание псевдопеременной result. Но в примерах встречается код, где похоже что просто возвращается значение последнего выражения. Это работает всегда или только в каких-то особых случаях?
1. Хотелось бы узнать более точный пример «Полноценного механизма», чтобы дать ответ. Потому что в разных языках — степень реализации разная.

2. Есть еще 2 способа, которые не описаны в документации: https://gist.github.com/Nyarum/059400eb32da81b8d901
1. Что бы можно было реализовать извлечение данных из аналога Option/Maybe из других языков.
case x of
 Some 0 -> 1
 Some x -> x*2
 Nothing -> 0


2. Самое интересное то и недокументировано.
1. Да, на этот вопрос ответили ниже.

2. На самом деле документировано, но не в определенном разделе. Другие способы есть в Internal documentation.
Thanks!
В Julia есть пакет, использующий макросы. Вероятно, это удачное решение при наличии менеджера пакетов.
Стоит отметить, что хэш-таблица из стандартной библиотеки Раста сделана с защитой от DoS атак, поэтому работает медленнее, чем могла бы.
Имеется в виду атака на коллизии в hash-функции, когда специально генирируются ключи, хэш от которых будет отдинаковый, что приводит к росту сложности с O(1) до O(n) -> увеличение времени обработки операций -> потенциально отказ в обслуживании.
Благодарю за наводку, прочитал всю документацию и все записи из блога: язык понравился. Буду следить за его развитием.
Предложу также сравнить с Bash:

grep -oP '\w+' $@ | sort | uniq -c

Штуки шутками, но этот вариант не сильно медленнее, учитывает русские слова и выдаёт человеческую сортировку (без учёта регистра). Nim, в частности, не учитывает русские слова и не умеет человечную сортировку. Такие мелочи как отсутствие русского языка огорчают. Как можно переписать код, чтобы \w в nim понимал UTF-8?
Сам спросил, сам нашёл:)
Переделать на \letter+ и дело в шляпе. Интересный язык, этот nim.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.