API Annotatons in a FunBind

Alan & Kim Zimmerman alan.zimm at gmail.com
Tue Dec 23 14:50:22 UTC 2014


The stuff I am desperate about is in D538. The diff came about through
implementing the functionality to actually use the API annotations, and it
showed up a number of shortcomings, each of which was trivial to fix and
does not have an impact on the rest.

The biggest of these is adding the fun_id,is_infix to the Match, which can
safely be ignored by anything except API annotations.

Effectively, without D538 the API annotations will not be usable in GHC 7.10

I do not believe it is any of big, pervasive, or destabilising. The largest
part of the diff is in fact adding detailed haddock documentation.

The various elements in this change are:

------------------------------------
HsTyLit now has SourceText

Update documentation of HsSyn to reflect which annotations are attached to
which element.

Ensure that the parser always keeps HsSCC and HsTickPragma values, to
be ignored in the desugar phase if not needed

Bringing in SourceText for pragmas

Add Location in NPlusKPat

Add Location in FunDep

Make RecCon payload Located

Explicitly add AnnVal to RdrName where it is compound

Add Location in IPBind

Add Location to name in IEThingAbs

Add Maybe (Located id,Bool) to Match to track fun_id,infix.  This includes
converting Match into a record and adding a note about why the fun_id needs
to be replicated in the Match.

Add Location in KindedTyVar

Sort out semi-colons for parsing

   - import statements
   - stmts
   - decls
   - decls_cls
   - decls_inst

--------------------------------------

So it is basically adding Located wrappers, SourceText fields,
documentation, and the extra stuff in Match.

Alan



On Tue, Dec 23, 2014 at 4:38 PM, Simon Peyton Jones <simonpj at microsoft.com>
wrote:

>  As you’ll see 7.10 RC1 is out.    The 7.10 boat has been advertised as
> sailing for weeks now.  Of course everyone very reasonably wants their
> thing in, but if we keep agreeing, 7.10 will never appear.
>
>
>
> If you are *absolutely desperate* to have something in that isn’t in yet,
> please say so in the most specific and concrete terms possible.  (I assume
> this Match stuff is not in the desperate category.)
>
>
>
> Anything big, pervasive, or destabilising is unlikely to get in for the
> reasons above.
>
>
>
> Simon
>
>
>
> *From:* Alan & Kim Zimmerman [mailto:alan.zimm at gmail.com]
> *Sent:* 23 December 2014 13:49
>
> *To:* Simon Peyton Jones
> *Cc:* ghc-devs at haskell.org
> *Subject:* Re: API Annotatons in a FunBind
>
>
>
> I suspect it will be possible to move the fun_id and is_infix information
> directly into the Match, since it seems to be used via a MatchWrapper for a
> Match each time.
>
> Should I attempt this, and if so should it be in D538? I am really keen to
> get this into 7.10, so do not want to push big changes through it it means
> missing the boat.
>
>
>
> In terms of the variations of (  + ), the whole thing is parsed as a
> RdrName, and carries API annotations.
>
> For interest, I dug through Parser.y when making test cases for
> ghc-exactprint and identified the following cases which all produce a
> RdrName, and have corresponding API Annotations.
>
>         |  'type' qcname            {% amms (mkTypeImpExp (sLL $1 $>
> (unLoc $2)))
>                                             [mj AnnType $1,mj AnnVal $2] }
>
>         | '(' qconsym ')'       {% ams (sLL $1 $> (unLoc $2))
>                                        [mo $1,mj AnnVal $2,mc $3] }
>
>         | '(' consym ')'        {% ams (sLL $1 $> (unLoc $2))
>                                        [mo $1,mj AnnVal $2,mc $3] }
>
>         | '`' conid '`'         {% ams (sLL $1 $> (unLoc $2))
>                                        [mj AnnBackquote $1,mj AnnVal $2
>                                        ,mj AnnBackquote $3] }
>
>         | '`' varid '`'         {% ams (sLL $1 $> (unLoc $2))
>                                        [mj AnnBackquote $1,mj AnnVal $2
>                                        ,mj AnnBackquote $3] }
>         | '`' qvarid '`'        {% ams (sLL $1 $> (unLoc $2))
>                                        [mj AnnBackquote $1,mj AnnVal $2
>                                        ,mj AnnBackquote $3] }
>
>         | '(' ')'                      {% ams (sLL $1 $> $ getRdrName
> unitTyCon)
>                                               [mo $1,mc $2] }
>         | '(#' '#)'                    {% ams (sLL $1 $> $ getRdrName
> unboxedUnitTyCon)
>                                               [mo $1,mc $2] }
>
>
>         | '(' commas ')'        {% ams (sLL $1 $> $ getRdrName (tupleTyCon
> BoxedTuple
>                                                         (snd $2 + 1)))
>                                        (mo $1:mc $3:(mcommas (fst $2))) }
>         | '(#' commas '#)'      {% ams (sLL $1 $> $ getRdrName (tupleTyCon
> UnboxedTuple
>                                                         (snd $2 + 1)))
>                                        (mo $1:mc $3:(mcommas (fst $2))) }
>         | '(' '->' ')'          {% ams (sLL $1 $> $ getRdrName funTyCon)
>                                        [mo $1,mj AnnRarrow $2,mc $3] }
>         | '[' ']'               {% ams (sLL $1 $> $ listTyCon_RDR) [mo
> $1,mc $2] }
>         | '[:' ':]'             {% ams (sLL $1 $> $ parrTyCon_RDR) [mo
> $1,mc $2] }
>         | '(' '~#' ')'          {% ams (sLL $1 $> $ getRdrName eqPrimTyCon)
>                                         [mo $1,mj AnnTildehsh $2,mc $3] }
>
>         | '(' qtyconsym ')'             {% ams (sLL $1 $> (unLoc $2))
>                                                [mo $1,mj AnnVal $2,mc $3] }
>         | '(' '~' ')'                   {% ams (sLL $1 $> $ eqTyCon_RDR)
>                                                [mo $1,mj AnnTilde $2,mc
> $3] }
>
> tyvarop : '`' tyvarid '`'       {% ams (sLL $1 $> (unLoc $2))
>                                        [mj AnnBackquote $1,mj AnnVal $2
>                                        ,mj AnnBackquote $3] }
>
> Alan
>
>
>
> On Tue, Dec 23, 2014 at 3:25 PM, Simon Peyton Jones <simonpj at microsoft.com>
> wrote:
>
>   Also, there is currently no location information for the fun_id for an
> infix definition, which can move around depending on the size of the left
> operand, and the choices made for whitespace.
>
>
>
> Good point.  So is the field only needed for an equation in infix form?
> Can we get rid of fun_infix, and replace with a mabe_infix field in the
> Match, used only for (a) FunBind that is (b) infix?
>
>
>
> In ordinary expressions I still don’t understand how you distinguish
>
>             map ( +) xs
>
> from
>
>             map (+ ) xs
>
>
>
> Simon
>
>
>
> *From:* Alan & Kim Zimmerman [mailto:alan.zimm at gmail.com]
> *Sent:* 23 December 2014 12:16
> *To:* Simon Peyton Jones
> *Cc:* ghc-devs at haskell.org
> *Subject:* Re: API Annotatons in a FunBind
>
>
>
>
>
> On Tue, Dec 23, 2014 at 1:59 PM, Simon Peyton Jones <simonpj at microsoft.com>
> wrote:
>
>  If you do this
>
> ·         Please make Match into a record (it ought to be already)
>
>  Ok
>
>  ·         Put a Note on the fun_id field, with an example like the one
> you give
>
>  Ok
>
>
>
> I’m not really sure if Haskell lets you mix infix and prefix notation for
> the same function definition, as you have done.  The Report is silent on
> this question. I’m inclined to think “no”.
>
>
>
>  Currently a FunBind has a fun_infix field saying whether the definition
> uses infix notation.  That is fine if “no” above.
>
>
>
> If all are prefix or infix, do you still need the new field in Match?
> Would it matter only for operators where you want to know where to put the
> parens?  Even in normal code, how are you distinguishing (+ ) from ( +) or
> whatever?
>
>
>
>
>
> The example I gave is an empirical test, it is currently accepted by GHC.
> The function as a whole is infix, it is just the alternate representation
> can be used for the individual Match definitions.
>
> There are straightforward rules as to whether a given fun_id needs parens
> or backquotes. The problem is that with source-to-source conversions the
> original must be reproduced exactly, and the code author has freedom to put
> arbitrary whitespace between the surrounding parens/backquotes and the
> actual identifier.  Hence the original fun_id is needed as an anchor for
> the API annotations.
>
> Also, there is currently no location information for the fun_id for an
> infix definition, which can move around depending on the size of the left
> operand, and the choices made for whitespace.
>
>
>
> In earlier versions of HaRe we were forced to scan through the rich token
> stream for a match to pick up this information.
>
> Alan
>
>
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-bounces at haskell.org] *On Behalf Of *Alan
> & Kim Zimmerman
> *Sent:* 15 December 2014 21:16
> *To:* ghc-devs at haskell.org
> *Subject:* API Annotatons in a FunBind
>
>
>
> After individual FunBinds have been parsed, they are combined in
> getMonoBind.
>
> In the process, all the original FunBind fun_id's bar one are discarded,
> including its location.
>
> This causes a problem for source-to-source conversions of functions such
> as the following
>
> (&&&  ) [] [] =  []
> xs    &&&   [] =  xs
> (  &&&  ) [] ys =  ys
>
> Where there are compound RdrNames, and each has different spacing.
>
> I am proposing to add a (Maybe (Located id)) to the Match datatype to deal
> with this.
>
>
> data Match id body
>   = Match
>
>         Maybe (Located id) -- fun_id in subsequent function equations
>
>         [LPat id]               -- The patterns
>         (Maybe (LHsType id))    -- A type signature for the result of the
> match
>                                 -- Nothing after typechecking
>         (GRHSs id body)
>
> Is this a problem?
>
> Alan
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141223/9ab8e0bb/attachment-0001.html>


More information about the ghc-devs mailing list