Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Malcolm Wallace

On 29 Apr 2013, at 07:00, Niklas Hambüchen wrote:

 I would like to propose the development of source code refactoring tool
 that operates on Haskell source code ASTs and lets you formulate rewrite
 rules written in Haskell.


Seen this?
http://www.haskell.org/haskellwiki/HaRe

Regards,
Malcolm
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Roman Cheplyaka
* Niklas Hambüchen m...@nh2.me [2013-04-29 14:00:23+0800]
 I would like to propose the development of source code refactoring tool
 that operates on Haskell source code ASTs and lets you formulate rewrite
 rules written in Haskell.

Hi Niklas,

This is a great idea. I talked about it at HIW last year[1] and have
been working on it since then.

[1]: http://www.youtube.com/watch?v=Ae-6uIMQPmU

1. What you call a full-source AST is already present in
   haskell-src-exts (under Annotated subtree). It /almost/ satisfies

 pretty .  parse = id,

   (one thing it fails to do is to preserve tabs), and fixing it should
   be definitely easier than starting from scratch.

2. HSE has two pretty-printers: an exact one, and one that ignores
   annotations and pretty-prints in its own style. It's important to
   have a mixture of both, so that we can pretty-print generated
   snippets and splice them into an already formatted AST. A friend of
   mine, Pavel Poukh, is working on a pretty-printer that produces an
   annotated tree instead of a flat string, and AFAIK that work is close
   to done.

   [2]: https://github.com/Pnom/haskell-ast-pretty

3. A major thing that I devoted my time to is name resolution and
   package management [3,4], which are necessary for the tool to work.

   [3]: https://github.com/feuerbach/haskell-names
   [4]: https://github.com/feuerbach/haskell-packages

   They are also close to done.

4. As for the tool itself, I have a crude prototype [5], but I
   haven't updated it for a while.

   [5]: https://github.com/feuerbach/hasfix

5. The user interface is, of course, an important topic by itself. I
   was thinking of something less expressive and more declarative, but
   your idea is also interesting. Let's discuss this separately.

Regarding this topic as a GSoC project, I'm not so sure this is a good
idea. As a past GSoC student myself, I feel that new projects (as
opposed to established projects with existing user base and development
team) have much greater risks. (This is also backed up by data [6].)

But if you (or anyone else who happens to read this) would like to get
involved, please get in touch with me!

[6]: http://www.gwern.net/Haskell Summer of Code

Roman

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Niklas Hambüchen
Hello Malcolm,

no, I had indeed not seen this! Thanks for the link.

It goes very much in the direction I was thinking of, but it does not
seem to maintained and does not cabal install either.

It also seems very much focused on interactive editor integration as
compared to written-out transformations.

Do you know to what extent they have built and a modification-friendly AST?
Also, do you know if the people involved in this are still active in the
community and interested in working further in this direction?

Thanks
Niklas

On 29/04/13 15:36, Malcolm Wallace wrote:
 
 On 29 Apr 2013, at 07:00, Niklas Hambüchen wrote:
 
 I would like to propose the development of source code refactoring tool
 that operates on Haskell source code ASTs and lets you formulate rewrite
 rules written in Haskell.
 
 
 Seen this?
 http://www.haskell.org/haskellwiki/HaRe
 
 Regards,
 Malcolm
 

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Alexander Kjeldaas
There is another aspect to this:  How do you get maintainers to apply the
patches?  How should hackage be changed to accomodate large-scale
refactorings?

There was a discussion on this mailing list related to build regressions on
GHC 7.6 last year.

All of the regressions could be fixed using perl regexps, and it was only a
few hours of work, much less than the work involved in the discussion
itself.  I downloaded all of hackage and did the fixes using perl.

http://www.haskell.org/pipermail/haskell-cafe/2012-August/103155.html

However, without the community infrastructure to actually apply the
patches, the problem is not solved.

I think this is mainly a community/organizational issue.  Refactoring is
not really the problem, but of course better refactoring abilities are good.

Alexander


On Mon, Apr 29, 2013 at 9:59 AM, Niklas Hambüchen m...@nh2.me wrote:

 Hello Malcolm,

 no, I had indeed not seen this! Thanks for the link.

 It goes very much in the direction I was thinking of, but it does not
 seem to maintained and does not cabal install either.

 It also seems very much focused on interactive editor integration as
 compared to written-out transformations.

 Do you know to what extent they have built and a modification-friendly AST?
 Also, do you know if the people involved in this are still active in the
 community and interested in working further in this direction?

 Thanks
 Niklas

 On 29/04/13 15:36, Malcolm Wallace wrote:
 
  On 29 Apr 2013, at 07:00, Niklas Hambüchen wrote:
 
  I would like to propose the development of source code refactoring tool
  that operates on Haskell source code ASTs and lets you formulate rewrite
  rules written in Haskell.
 
 
  Seen this?
  http://www.haskell.org/haskellwiki/HaRe
 
  Regards,
  Malcolm
 

 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Simon Hengel
Hi Niklas,
I haven't read the whole proposal as I'm short of time.  But Alan
Zimmerman is doing a lot of work on integrating HaRe with the GHC API
[1].  He is alanz on freenode and a regular in #hspec.

I haven't looked at the code, but maybe it's of interest to you.

Cheers,
Simon

[1] https://github.com/alanz/HaRe/tree/ghc-api

On Mon, Apr 29, 2013 at 02:00:23PM +0800, Niklas Hambüchen wrote:
 I would like to propose the development of source code refactoring tool
 that operates on Haskell source code ASTs and lets you formulate rewrite
 rules written in Haskell.
 
 Objective
 -
 
 The goal is to make refactorings easier and allow global code changes
 that might be incredibly tedious to do in a non-automated way.
 By making these transformations convenient, we can make it easier to
 maintain clean code, add new features or clean up leftovers faster, and
 reduce the fear and effort to upgrade to newer versions of packages and
 APIs.
 
 
 Transformations
 ---
 
 First, here are a few operations you would use this tool for. Some of
 them are common operations you would also do in other programming
 languages, some are more specific to Haskell.
 
 * Changing all occurrences of import Prelude hiding (catch) to import
 qualified Control.Exception as E
 
 * Replacing all uses of a function with that function being imported
 qualified or the other way around
 
 * Adding a field to data constructor a record, setting user-supplied
 defaults for construction and destruction:
 
 -- Suppose you want to change one of these
 data User = User { name :: String, age :: Int }
 data User = User String Int
 
 -- into one of these
 data User = User { name :: String, age :: Int, active :: Bool }
 data User = User String Int Bool
 
 -- the refactoring tool could perform, in all relevant locations:
 show (User name age) = ...
 show (User name age _) = ...
 
 -- and also this transformation:
 ... u { name = deleted } ...
 ... u { name = deleted, active = False } ...
 
 -- or equivalently with records.
 
 -- Special cases could be taken care of as specified, such as
 --   whenever an object of [this User type] has
 --of its records passed into some function 'email', do this
 --now only if the user is active, so modify all relevant code
 --email (name u)
 --to
 --if (active u) then email (name u) else return ()
 
 -- Other examples include adding a position counter to attoparsec.
 
 * Adding a type parameter to a type
 
 -- This happens a lot on monad transformer stacks, e.g.
 newtype MyMonad a b c = MyMonad (ReaderT a (WriterT b ...
 
 -- and as you would probably agree on, this is not the most
 -- comfortable change to make; in big project this can mean
 -- hour-long grinding.
 
 -- It has also recently happened in the basic underlying types
 -- of packages like conduit and pipes.
 
 * Adding a new transformer around a monad
 
 * Addressing problems like mentioned in
 http://blog.ezyang.com/2012/01/modelling-io/:
   There is one last problem with this approach: once the primitives
 have been selected, huge swaths of the standard library have to be
 redefined by “copy pasting” their definitions ...
 
 * Extracting a value into a let or where clause
 
 * Renaming a variable, and all its occurrences that are semantically
 same variable (based on its scope)
 
 * Changing the way things are done, such as:
 
 * Replacing uses of fmap with $, also taking care of the
   corresponding import, and such cases were partial application
   is involved
 
 * Replacing uses of when (isJust) to forM_
 
 * Making imports clearer by adding all functions used to the file to the
 import list of the module that gets them in scope
 
 * Finding all places where an exported function does not have all its
 arguments haddock-documented.
 
 * Performing whole-project refactorings instead of operating on single
 files only, allowing operations like
 
 Find me all functions of this type, e.g.
  Maybe a - (a - m a) - m a
  in the project and extract them into this new module,
  with the name 'onJust'.
 
 
 Some of the problems above can be tried to address using regex-based
 search and replace, but this already fails in the simplest case of
 import Prelude hiding (catch) in case there is more than that imported
 from Prelude or newlines involved in the import list.
 
 Transformation on the AST are much more powerful, and can guarantee that
 the result is, at least syntactically, valid. No text base tool can do that.
 
 
 Other uses
 --
 
 In addition to being able to perform transformations as mentioned above,
 the refactoring tool as a library can be leveraged to:
 
 * Support or be the base of code formatting tools such as
 haskell-stylish, linters, style/convention checkers, static analyzers,
 test coverage tools etc.
 
 * Implement automatic API upgrades.
 

Re: [Haskell-cafe] GSoC proposal: Haskell AST-based refactoring and API upgrading tool

2013-04-29 Thread Davorak
The latest updates on HaRe with GHC API project seem to be posted on the 
google+ community page:
https://plus.google.com/communities/116266567145785623821



On Monday, April 29, 2013 5:09:56 AM UTC-5, Simon Hengel wrote:

 Hi Niklas,
 I haven't read the whole proposal as I'm short of time.  But Alan
 Zimmerman is doing a lot of work on integrating HaRe with the GHC API
 [1].  He is alanz on freenode and a regular in #hspec.

 I haven't looked at the code, but maybe it's of interest to you.

 Cheers,
 Simon

 [1] https://github.com/alanz/HaRe/tree/ghc-api

 On Mon, Apr 29, 2013 at 02:00:23PM +0800, Niklas Hambüchen wrote:
  I would like to propose the development of source code refactoring tool
  that operates on Haskell source code ASTs and lets you formulate rewrite
  rules written in Haskell.
  
  Objective
  -
  
  The goal is to make refactorings easier and allow global code changes
  that might be incredibly tedious to do in a non-automated way.
  By making these transformations convenient, we can make it easier to
  maintain clean code, add new features or clean up leftovers faster, and
  reduce the fear and effort to upgrade to newer versions of packages and
  APIs.
  
  
  Transformations
  ---
  
  First, here are a few operations you would use this tool for. Some of
  them are common operations you would also do in other programming
  languages, some are more specific to Haskell.
  
  * Changing all occurrences of import Prelude hiding (catch) to import
  qualified Control.Exception as E
  
  * Replacing all uses of a function with that function being imported
  qualified or the other way around
  
  * Adding a field to data constructor a record, setting user-supplied
  defaults for construction and destruction:
  
  -- Suppose you want to change one of these
  data User = User { name :: String, age :: Int }
  data User = User String Int
  
  -- into one of these
  data User = User { name :: String, age :: Int, active :: Bool }
  data User = User String Int Bool
  
  -- the refactoring tool could perform, in all relevant locations:
  show (User name age) = ...
  show (User name age _) = ...
  
  -- and also this transformation:
  ... u { name = deleted } ...
  ... u { name = deleted, active = False } ...
  
  -- or equivalently with records.
  
  -- Special cases could be taken care of as specified, such as
  --   whenever an object of [this User type] has
  --of its records passed into some function 'email', do this
  --now only if the user is active, so modify all relevant code
  --email (name u)
  --to
  --if (active u) then email (name u) else return ()
  
  -- Other examples include adding a position counter to attoparsec.
  
  * Adding a type parameter to a type
  
  -- This happens a lot on monad transformer stacks, e.g.
  newtype MyMonad a b c = MyMonad (ReaderT a (WriterT b ...
  
  -- and as you would probably agree on, this is not the most
  -- comfortable change to make; in big project this can mean
  -- hour-long grinding.
  
  -- It has also recently happened in the basic underlying types
  -- of packages like conduit and pipes.
  
  * Adding a new transformer around a monad
  
  * Addressing problems like mentioned in
  http://blog.ezyang.com/2012/01/modelling-io/:
There is one last problem with this approach: once the primitives
  have been selected, huge swaths of the standard library have to be
  redefined by “copy pasting” their definitions ...
  
  * Extracting a value into a let or where clause
  
  * Renaming a variable, and all its occurrences that are semantically
  same variable (based on its scope)
  
  * Changing the way things are done, such as:
  
  * Replacing uses of fmap with $, also taking care of the
corresponding import, and such cases were partial application
is involved
  
  * Replacing uses of when (isJust) to forM_
  
  * Making imports clearer by adding all functions used to the file to the
  import list of the module that gets them in scope
  
  * Finding all places where an exported function does not have all its
  arguments haddock-documented.
  
  * Performing whole-project refactorings instead of operating on single
  files only, allowing operations like
  
  Find me all functions of this type, e.g.
   Maybe a - (a - m a) - m a
   in the project and extract them into this new module,
   with the name 'onJust'.
  
  
  Some of the problems above can be tried to address using regex-based
  search and replace, but this already fails in the simplest case of
  import Prelude hiding (catch) in case there is more than that imported
  from Prelude or newlines involved in the import list.
  
  Transformation on the AST are much more powerful, and can guarantee that
  the result is, at least syntactically, valid. No text base tool can do 
 that.