         # ... before after <=> (3 18.84 28.27)(4 25.13 50.26)
         name = node[1]
         {vars} = node.scopeNode
-        if (v = vars["get_#{name}"])?.type is 'F'
+        if (v = vars["get_#{name}"])?.category is VERB
           [LDC, APLArray.zero, GET, v.scopeDepth, v.slot, MON]
         else
           v = vars[name]

        when 'assign' then visitLHS node[1], visit node[2]
        when 'symbol'
          name = node[1]
          if (v = vars["get_#{name}"])?.type is 'F'
            type: 'X'
          else
            vars[name] or err node, "Symbol '#{name}' is referenced before assignment."
        when 'lambda'
          queue.push extend (body = node[1]),
            scopeNode: scopeNode
            scopeDepth: (d = scopeNode.scopeDepth + 1 + !!(node.isAdverb or node.isConjunction))
            nSlots: 3
            vars: v = extend Object.create(vars),
              '⍵': type: 'X', slot: 0, scopeDepth: d
              '∇': type: 'F', slot: 1, scopeDepth: d
              '⍺': type: 'X', slot: 2, scopeDepth: d
          if node.isConjunction
            v['⍵⍵'] = v['⍹'] = type: 'F', slot: 0, scopeDepth: d - 1
            v['∇∇'] =          type: 'F', slot: 1, scopeDepth: d - 1, isConjunction: true
            v['⍺⍺'] = v['⍶'] = type: 'F', slot: 2, scopeDepth: d - 1
          else if node.isAdverb
            v['⍺⍺'] = v['⍶'] = type: 'F', slot: 0, scopeDepth: d - 1
            v['∇∇'] =          type: 'F', slot: 1, scopeDepth: d - 1, isAdverb: true
          type: 'F', isAdverb: node.isAdverb, isConjunction: node.isConjunction
        when 'string', 'number', 'embedded' then type: 'X'
        when 'index'
          for i in [2...node.length] by 1 when c = node[i]
            visit(c).type is 'X' or err node, 'Only expressions of type data can be used as an index.'
          visit node[1]
        when 'expr'
          a = node[1..]

  opts.aplCode = aplCode
  compileAST parse(aplCode, opts), opts

macro withLexicalCategoryConstants (f) ->
  f.subst
    NOUN:        macro.valToNode 1
    VERB:        macro.valToNode 2
    ADVERB:      macro.valToNode 3
    CONJUNCTION: macro.valToNode 4

compileAST = withLexicalCategoryConstants (ast, opts = {}) ->
  ast.scopeDepth = 0
  ast.nSlots = if prelude then prelude.ast.nSlots else 0
  ast.vars = if prelude then Object.create prelude.ast.vars else {}
  do ->
    opts.ctx ?= Object.create vocabulary
    for k, v of opts.ctx when not ast.vars[k]
      ast.vars[k] = varInfo = category: NOUN, slot: ast.nSlots++, scopeDepth: ast.scopeDepth
      if typeof v is 'function' or v instanceof λ
        varInfo.category = if v.isAdverb then ADVERB else if v.isConjunction then CONJUNCTION else VERB
        if /^[gs]et_.*/.test k then ast.vars[k[4..]] = category: NOUN

  err = (node, message) ->
    syntaxError message, file: opts.file, line: node.startLine, col: node.startCol, aplCode: opts.aplCode
