Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 09:11
Оценка:
У меня вопрос о правильности функционирования #pragma indent
#pragma indent
...
module Main
        public rulesAplayer(Source:string, Rules:string):TRulesAplayerResult
            def LexedSource = SourceLexer().Parse(Source);
            def ParsedRules = RulesParser().Parse(Rules);
            def listRuleTokenWithNamedLinkToListString(RuleToken)
            {
                RuleToken.Filter(ruleSourceTokens => ruleSourceTokens.RuleTokenValue is TRuleTokenValue.NamedLink)
                .Map(token => token.RuleTokenValue.getNameOrValue())
            }
            def isRulesSourcePartHaveDublicatesOfNamedLinks(Rules)
                !Rules.ToArray().ForAll((ruleSource, _) => 
                    listRuleTokenWithNamedLinkToListString(ruleSource)
                    .Group(String.Compare)
                    .ToArray().ForAll(groupedEqualTokens => List(groupedEqualTokens).Count==1)
                );
            def isRulesDestinationPartHaveUnknowenOfNamedLinks(Rules)
                !Rules.ToArray().ForAll( (ruleSource, ruleDestination) => 
                {
                    def correctIdentificators = listRuleTokenWithNamedLinkToListString(ruleSource);
                    def DestinationPartOfRule=listRuleTokenWithNamedLinkToListString(ruleDestination);
                    DestinationPartOfRule.ForAll(correctIdentificators.Contains)
                });
            if(LexedSource.IsNone)
                TRulesAplayerResult.Error("Cant lex source text.")
            else
                if(ParsedRules.IsNone)
                    TRulesAplayerResult.Error("Cant parse rules.")
                else
...

Если вы заметите, то осталось несколько {} и убрать их не получается не потеряв в читабельности. А если просто убрать, то ошибки компиляции вылазят. В чем причины и как бороться с этим?
И самое главное: Какие правила? В каких случаях нужно ставить {}, а в каких нет? Мне эти правила не кажутся очевидными и закономерными. Я их просто не могу вывести. Как будто это сам господин рандом пожелал, что ставить скобки нужно именно здесь для успешной компиляции.
Не говоря уже о неудобстве работы с PegGrammar, тк, насколько я понял, в режиме prgama indent атрибут должен быть записан в одну строчку в той же строчке, что и class. Ок, на самом деле это не проблема, а достаточно без prgama indent вынести в отдельный файл парсер. Может это не всегда удобно, но не вызывает больших проблем. А вот в случае с не очевидными правилами расстановки {} — это превращается в проблему. Впрочем причины этого я понимаю. #pragma indent прикручена в язык сбоку.
Собственно, ещё раз вопрос: Каковы правила расстановки {} в режиме #pragma indent?


11.09.12 15:56: Ветка выделена из темы Ошибки из-за pragma indent
Автор: Meldor
Дата: 05.09.12
— VladD2
Re: Ошибки из-за pragma indent
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.09.12 12:02
Оценка:
Здравствуйте, Аноним, Вы писали:

А>У меня вопрос о правильности функционирования #pragma indent

А>Если вы заметите, то осталось несколько {} и убрать их не получается не потеряв в читабельности. А если просто убрать, то ошибки компиляции вылазят. В чем причины и как бороться с этим?

А>#pragma indent
А>...
А>            def listRuleTokenWithNamedLinkToListString(RuleToken)
А>            {
А>                RuleToken.Filter(ruleSourceTokens => ruleSourceTokens.RuleTokenValue is TRuleTokenValue.NamedLink)
А>                .Map(token => token.RuleTokenValue.getNameOrValue())
А>            }


Тут проблем быть не должно. Просто убирай скобки, а при переносе строк используй "\".

А>                !Rules.ToArray().ForAll( (ruleSource, ruleDestination) => 
А>                {
А>                    def correctIdentificators = listRuleTokenWithNamedLinkToListString(ruleSource);
А>                    def DestinationPartOfRule=listRuleTokenWithNamedLinkToListString(ruleDestination);
А>                    DestinationPartOfRule.ForAll(correctIdentificators.Contains)
А>                });


Тут придется использовать не макрос =>, а базовый синтаксис лямбд:

fun(ruleSource, ruleDestination)
  def correctIdentificators = listRuleTokenWithNamedLinkToListString(ruleSource);
  def DestinationPartOfRule=listRuleTokenWithNamedLinkToListString(ruleDestination);
  DestinationPartOfRule.ForAll(correctIdentificators.Contains)


А>И самое главное: Какие правила? В каких случаях нужно ставить {}, а в каких нет?


Да когда хочешь тогда и ставь. Вот только если врубил скобки, то внутри уже нужно со скобками жить.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 12:35
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Тут проблем быть не должно. Просто убирай скобки, а при переносе строк используй "\".

Хм, это помогло. Но в чем причина? Код ниже в функции isRulesSourcePartHaveDublicatesOfNamedLinks не использует \, но использует строки начинающиеся с . .

VD>Тут придется использовать не макрос =>, а базовый синтаксис лямбд:

С чем это связано? Вон код функции isRulesSourcePartHaveDublicatesOfNamedLinks использует (ruleSource, _) => и никаких скобочек расставлять не пришлось. Или это из-за начала лямбды с def?
def isRulesDestinationPartHaveUnknowenOfNamedLinks(Rules)
                !Rules.ToArray().ForAll(
                    fun (ruleSource, ruleDestination)
                        def correctIdentificators = listRuleTokenWithNamedLinkToListString(ruleSource);
                        def DestinationPartOfRule=listRuleTokenWithNamedLinkToListString(ruleDestination);
                        DestinationPartOfRule.ForAll(correctIdentificators.Contains)
                    )

Написал fun, не помогло:

(37,11)parse error near keyword `def': expected `{' at the beginning of function body
(37,11): error : expected `;'
(37,11): error : parse error near identifier `correctIdentificators': unexpected token after expression in sequence (you forget a closing bracket?).

Вернул {} и снова работает.
Re[3]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 12:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>...Вернул {} и снова работает.


Я вот тоже, как большой любитель питона полез сначала писать код на Nemerle с использованием #pragma indent
Помучавшись, забил, и сменил религию с отступной на скобочную.
Немерлевские макры один фиг все перевешивают...
Re[3]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 12:51
Оценка:
Здравствуйте, Аноним, Вы писали:

Какая версия компилятора ?

Так вполне работает

#pragma indent

using System.Console;

class A
  static Main() : void
    def x()
      [1,2,3].Find(x =>
      {
        def p = 1;
        x > p
      })
    x()
Re[4]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 13:00
Оценка:
А>Какая версия компилятора ?
NemerleSetup-v1.1.854.0-nightly

А>Так вполне работает

Ну ещё бы. Скобки указаны. У меня тоже со скобками периодически работает. Только не очень понятно где можно пихнуть без скобок, а где скобки нужны 100%, а где нужно использовать fun вместо => ради убирания {}, а где \.
Я даже склоняюсь к тому, чтобы убрать привычный из F#/Python #prgama indent и писать со скобками {} всегда...

Кстати, почему нет ForAll в листе и приходится ToArray() вызывать?
Re[5]: Ошибки из-за pragma indent
От: _NN_ www.nemerleweb.com
Дата: 11.09.12 14:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>Какая версия компилятора ?

А>NemerleSetup-v1.1.854.0-nightly

А>>Так вполне работает

А>Ну ещё бы. Скобки указаны. У меня тоже со скобками периодически работает. Только не очень понятно где можно пихнуть без скобок, а где скобки нужны 100%, а где нужно использовать fun вместо => ради убирания {}, а где \.
Да, это нужно смотреть как препроцессор это обрабатывает.

А>Я даже склоняюсь к тому, чтобы убрать привычный из F#/Python #prgama indent и писать со скобками {} всегда...

Если не хотите заняться компилятором и исправить, то придется.

А>Кстати, почему нет ForAll в листе и приходится ToArray() вызывать?

ForAll есть: https://github.com/rsdn/nemerle/blob/master/lib/list.n#L395

Вообще проще юзать System.Linq.Enumerable методы
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 16:30
Оценка:
А>>Я даже склоняюсь к тому, чтобы убрать привычный из F#/Python #prgama indent и писать со скобками {} всегда...
_NN>придется.
То есть это пока только из-за недоработки компилятора. Спасибо.

_NN>ForAll есть

Я знаю. Только вот приходиться уточнять ToArray() чтобы ForAll сработал над list/List или приходиться писать List(выражение), чтобы преобразовывать из list. Например, если хочешь спросить l.Count, то приходиться list кастить до List. Или например стандартная функция Map возвращает list, а результат Map нам нужен для функции принимающей List в качестве параметра. В результате пока не скастишь константу-результат работы Map, то он в ошибках говорит, что функция Map не найдена (точнее говорит, что не может выбрать нужную перегрузку Map). Это выглядит очень непривычно, когда выбор перегрузки функции зависит от требуемого результа. о_О

Кстати, а почему нельзя делать match что-то типа:
| Some([var]) => используем полученный var
Вроде F# с этим справлялся.

Ну и не хватает какого-нибудь sequence comprehension, как в F#. То есть обычный лист, только реализованный через yield (ленивый лист \ лист реализованный через блок-итераторов).
Re[6]: Ошибки из-за pragma indent
От: Аноним  
Дата: 11.09.12 16:37
Оценка:
_NN>Вообще проще юзать System.Linq.Enumerable методы
Ну стандартные Linq методы мне почему то кажутся какими то переполненными, неудобными и с непривычными названиями. А так с любого языка пришёл в Nemerle и пользуешься знакомыми стандартодефакто функциями. А так придется залазить в справочник и искать подходящий метод из того, что там майкрософт придумала...
Re[7]: Ошибки из-за pragma indent
От: _NN_ www.nemerleweb.com
Дата: 12.09.12 07:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Я даже склоняюсь к тому, чтобы убрать привычный из F#/Python #prgama indent и писать со скобками {} всегда...

_NN>>придется.
А>То есть это пока только из-за недоработки компилятора. Спасибо.

_NN>>ForAll есть

А>Я знаю. Только вот приходиться уточнять ToArray() чтобы ForAll сработал над list/List или приходиться писать List(выражение), чтобы преобразовывать из list. Например, если хочешь спросить l.Count, то приходиться list кастить до List. Или например стандартная функция Map возвращает list, а результат Map нам нужен для функции принимающей List в качестве параметра. В результате пока не скастишь константу-результат работы Map, то он в ошибках говорит, что функция Map не найдена (точнее говорит, что не может выбрать нужную перегрузку Map). Это выглядит очень непривычно, когда выбор перегрузки функции зависит от требуемого результа. о_О

Если вам нужен list, то нужно знать его полезный свойства и ограничения.
list это связанный список, а значит посчитать его длину берет линейное время.
Кроме того он иммутабельный в отличии от SCG.List.

А>Кстати, а почему нельзя делать match что-то типа:

А>| Some([var]) => используем полученный var
А>Вроде F# с этим справлялся.
def a = Some([1]);
 
match (a)
{
  | Some([x]) => System.Console.WriteLine(x);
  | _ => ()
}


http://ideone.com/orM85

А>Ну и не хватает какого-нибудь sequence comprehension, как в F#. То есть обычный лист, только реализованный через yield (ленивый лист \ лист реализованный через блок-итераторов).

Есть несколько вариантов.
List comprehension:
https://github.com/rsdn/nemerle/wiki/Basic-List-Construction
https://github.com/rsdn/nemerle/wiki/Basic-List-Construction-2

Computation Expressions:
https://github.com/rsdn/nemerle/wiki/Computation-Expression-macro
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: Ошибки из-за pragma indent
От: Аноним  
Дата: 16.09.12 10:19
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Если вам нужен list, то нужно знать его полезный свойства и ограничения.

_NN>list это связанный список, а значит посчитать его длину берет линейное время.
_NN>Кроме того он иммутабельный в отличии от SCG.List.

Я это понимаю, только почему компилятор Map не может найти подходящий для листа, пока результат до List не касатанешь?

_NN>
_NN>def a = Some([1]);
 
_NN>match (a)
_NN>{
_NN>  | Some([x]) => System.Console.WriteLine(x);
_NN>  | _ => ()
_NN>}
_NN>


_NN>http://ideone.com/orM85


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

А>>Ну и не хватает какого-нибудь sequence comprehension, как в F#. То есть обычный лист, только реализованный через yield (ленивый лист \ лист реализованный через блок-итераторов).

_NN>List comprehension:
_NN>https://github.com/rsdn/nemerle/wiki/Basic-List-Construction

_NN>Computation Expressions:

_NN>https://github.com/rsdn/nemerle/wiki/Computation-Expression-macro

List comprehension — не лениое создание листа и лист создается.
А вот это попробую, спасибо:
comp list { for(mutable i=0;i<n;i++) yield i }


Какие монады (и если помните их названия в стандртной библиотеке, чтобы погуглить) уже реализованны в стандартной библиотеке Немерле и какую либу для этого подключить? MList и ContBuilder ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.