1

If you were to run across code like this in your travels would the short names bother you?

let setPropertyAssignment = 
    parser {
        let! a = setIdentifierName
        let! b = propertyName
        let! c = openParenthesis 
        let! d = propertySetParameterList
        let! e = closeParenthesis 
        let! f = openCurlyBracket 
        let! g = functionBody
        let! h = closeCurlyBracket
        return Node(NodeType.PropertyAssignment, [a;b;c;d;e;f;g;h])
    }

Here is the largest parser in the project:

let iterationStatement = 
    parser {
        let! a = doKeyWord
        let! b = statement
        let! c = whileKeyWord
        let! d = openParenthesis
        let! e = expression
        let! f = closeParenthesis
        let! g = statementTerminator
        let symbols = [a; b; c; d; e; f; g]
        return Node(NodeType.IterationStatement, symbols)
    } +++ parser {
        let! a = whileKeyWord
        let! b = openParenthesis
        let! c = expression
        let! d = closeParenthesis
        let! e = statement
        let symbols = [a; b; c; d; e]
        return Node(NodeType.IterationStatement, symbols)
    } +++ parser {
        let! a = forKeyWord
        let! b = openParenthesis
        let! c = maybeOne expressionNoIn
        let! d = semiColon
        let! e = maybeOne expression
        let! f = semiColon
        let! g = maybeOne expression
        let! h = closeParenthesis
        let! i = statement
        let symbols = [a;b] @ c @ [d] @ e @ [f] @ g @ [h;i]              
        return Node(NodeType.IterationStatement, symbols)
    } +++ parser {
        let! a = forKeyWord
        let! b = openParenthesis
        let! c = varKeyWord
        let! d = variableDeclarationListNoIn
        let! e = semiColon
        let! f = maybeOne expression
        let! g = semiColon
        let! h = maybeOne expression
        let! i = closeParenthesis
        let! j = statement
        let symbols = [a;b;c;d;e] @ f @ [g] @ h @ [i;j]
        return Node(NodeType.IterationStatement, symbols)
    } +++ parser {
        let! a = forKeyWord
        let! b = openParenthesis
        let! c = leftHandSideExpression
        let! d = inKeyWord
        let! e = expression
        let! f = closeParenthesis
        let! g = statement
        let symbols = [a;b;c;d;e;f;g]               
        return Node(NodeType.IterationStatement, symbols)
    }  +++ parser {
        let! a = forKeyWord
        let! b = openParenthesis
        let! a = varKeyWord
        let! c = variableDeclarationNoIn
        let! a = inKeyWord
        let! c = expression
        let! d = closeParenthesis
        let! e = statement
        let symbols = [a; b; c; d; e]
        return Node(NodeType.IterationStatement, symbols)
    }
2

The singe char variable names keeps the important parts readable. To my eye that is much more valuable that naming the throwaway variables.

I know little about F#, but if something like the example below is possible I would find that slightly more straightforward since there are not extra assignments involved:

let setPropertyAssignment = 
  parser {
    return Node(NodeType.PropertyAssignment,
                  [
                   Lazy.force setIdentifierName;
                   Lazy.force propertyName;
                   Lazy.force openParenthesis;
                   Lazy.force propertySetParameterList;
                   Lazy.force closeParenthesis;
                   Lazy.force openCurlyBracket;
                   Lazy.force functionBody;
                   Lazy.force closeCurlyBracket
                  ]
               )
  }
  • I think the line "The singe char variable names keeps the important parts readable." really is the key here. As long as my parsers have proper names this should be a non issue. – ChaosPandion Sep 16 '10 at 18:47
  • Out of my own curiosity is it possible to inline the forcing instead of all the let!s or is my lack of F# experience showing? – Bill Sep 16 '10 at 21:25
  • It is showing... :) although with a bit of work I could get something similar working. – ChaosPandion Sep 17 '10 at 5:31
  • At least in the other .net languages there is often a performance penalty in assigning intermediate variables, so it might be worth trying. F# and I are still at the "you give me a headache" stage so I don't claim to be able to come up with valid syntax... – Bill Sep 17 '10 at 12:44
2

Depends on the complexity. With something this size, it's pretty obvious what you're doing and why. Make it much bigger--a page or so--and it'll get very confusing very quickly.

  • I updated my question to include the largest parser. – ChaosPandion Sep 15 '10 at 20:58
1

You'd benefit from a wrapper function that takes a list of parsers of 'a (your a to i above) and returns a single parser of 'a list. That way you wouldn't need to assign names to these intermediate parsers; you could drop them directly into a list.

  • You know that is very tempting but I am not sure how I will integrate error handing into the parsers yet. I will keep this in mind though. (This is my first parser combinator project so I wanted to reinvent the wheel as they say so I can understand how everything works.) – ChaosPandion Sep 15 '10 at 22:35
  • Understood. The Parsec/FParsec approach is to not return 'a directly, but to return a union of either Ok of 'a or Error of string. – Tim Robinson Sep 16 '10 at 8:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.