Re[2]: Язык Nemerle.Часть 2
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.02.11 22:46
Оценка: 2 (1)
Здравствуйте, Real 3L0, Вы писали:

R3>В качестве одного из преимуществ языка приводится то, что его легче читать.

R3>Где-то это явно видно, но где-то — мне ещё пока трудно перестроить мышление.

Как часто бывает нашей жизни преимущества порождают и недостатки.

R3>1. Непревычно, что начало точки разбора функции, по сути, находится в самом конце. Ну, тут причина понятна, это я просто брюзжу.


Не, на самом деле так оно и есть. С одной стороны то что функции объявляются перед их использованием действительно мешает изучать код основной функции. Но с другой это позволяет использовать в таких функциях замыкания.

Но этот недостаток нивелируется при использовании IDE. В VS локальные функции по умолчанию свернуты и тот же самый код будет выглядеть так:
def lexer(text : string) : list[Token]
{
  mutable index = 0;
  
+ def peek() : char
+ def read() : char
+ def isDigit(ch) { ch >= '0' && ch <= '9' }
+ def loop(resultTokens : list[Token]) : list[Token]
  
  loop([])
}

Для изучения конкретной функции просто нажимаем на "+" и получаем что-то вроде:
def lexer(text : string) : list[Token]
{
  mutable index = 0;
  
+ def peek() : char
+ def read() : char
+ def isDigit(ch) { ch >= '0' && ch <= '9' }

- def loop(resultTokens : list[Token]) : list[Token]
  {
+   def number(ch : char, accumulator : int = 0) : int
+   def error()
    
    def ch = read();

    match (ch)
    {
      | ' ' | '\t'            => loop(resultTokens) // игнорируем пробелы
      | '+' | '-' | '*' | '/' => loop(Token.Operator(ch.ToString()) :: resultTokens)
      | '\0'                  => resultTokens.Reverse()
      | _ when isDigit(ch)    => loop(Token.Number(number(ch)) :: resultTokens)
      | _                     => error()
    }
  }
  
  loop([])
}

и так далее.

R3>2. Непревычно, что новые элементы в список resultTokens добавляются с начала, что приводит к необходимости переворачивать список. Я, конечно, понимаю, что пример специальный, но не мог бы кто-нибудь преобразовать функцию так, чтобы новые элементы в resultTokens добавлялись в конец? Если это возможно. (Не обязательно дословно точно.)


Это уже особенность не языка, а структуры данных list[T]. Она так же вела бы себя и в любом другом языке. Все без исключения ФЯ имеют подобную структуру данных. Ее главная особенность — она неизменяемая. Однажды создав список они останется таковым до того момента когда GC его соберет за ненадобностью. А в функциональном коде неизменяемость — это большое достоинство. Кроме того неизменяемость позволяет порождать из одного списка другой не создавая его копии.
Следующим достоинством является константное (О(1)) время вставки.
Но все это возможно только в следствии того, что список строится от хвоста к голове.
Очень часто это даже является преимуществом. Но при сборке списка его приходится разворачивать.
В большинстве случаев это не является проблемой. К тому же зачастую список обрабатывается не по одному разу и он сам собой разворачивается. А иногда вообще не важен порядок элементов.

Ну, и в конце концов никто не запрещает использовать и другие типы данных. Например System.Collections.Generic.List[T].
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.