Pugs on stack

hiratara @ FreakOut!

August 21, 2015

Do you know Pugs?

What is “Pugs”?

  • a Haskell-based implementation of Perl6
  • “Perl6 User Golfing System”
  • Contributes to the design of Perl6

History of Pugs

  • Started on 2005-2-1 by Audrey Tang
  • YAPC::Asia 2006 Tokyo
    • Audrey Tang, “Introduction to Pugs”
  • Was suddenly unmaintained in 2007
  • Feature comparison of Perl 6 compilers
    • “not being actively maintained, many things are broken

Where is source codes?

pugs-6.2.13.20130611

  • not a 6.28.x release but the latest 6.2.x
  • “the Pugs.hs project exists mainly for historical/archival purposes”
  • Build with ghc-7.6.3
  • You can install it by using cabal

Improvement of Haskell

  • 2013-4-21 ghc-7.6.3
  • 2014-4-9 ghc-7.8.1
  • 2014-4-12 ghc-7.8.2
  • 2014-7-11 ghc-7.8.3
  • 2014-12-23 ghc-7.8.4
  • 2015-3-27 ghc-7.10.1
  • 2015-7-29 ghc-7.10.2

A lot of breaking changes

  • ghc-7.8
    • Typeable is now poly-kinded
    • user-written instances of Typeable are now disallowed
    • Roles - Nominal, Representational, and Phantom
    • Some bugs of functional dependencies are fixed
  • ghc-7.10
    • Prelude are re-exported from more generic modules
    • Applicative typeclass becomes a superclass of Monad

Cabal isn’t newbie friendly

  • Strict versioning causes dependency hell
  • You need to use cabal sandbox
  • It takes a long time to install all dependenies

stack 0.1

  • An alternative of cabal-install
  • Provide reproducible build
  • Fix versions of all packages by using Stackage
  • public beta quality

Just write stack.yaml

packages:
- HsParrot/
- HsPerl5/
- HsSyck/
- MetaObject/
- Pugs/
- pugs-compat/
- pugs-DrIFT/
extra-deps:
- FindBin-0.0.5
- control-timeout-0.1.2
- stringtable-atom-0.0.7
resolver: lts-2.20

Pugs-6.2.13.20150815

  • Build with ghc-7.10.2
  • You can install it by using stack

You only have to do

Install stack and libperl-dev, libtinfo-dev, then:

$ git clone git@github.com:perl6/Pugs.hs.git
$ cd Pugs.hs
$ stack build --install-ghc
$ stack exec -- pugs

How is Pugs doing?

A popular Perl6 benchmark:

It’s very slow

% time pugs -e 'my $i=0; for (1..5_000) { $i++ }; say $i'
5000
pugs  0.23s user 0.01s system 98% cpu 0.239 total
  • Run as the interpreter
  • All eveluation in Eval monad
  • A stack of Monad Transformers
newtype Eval a = EvalT ContT (EvalResult Val) (ReaderT Env SIO) (EvalResult a)
data EvalResult a
    = RNormal    !a
    | RException !Val

50ms or die

CPS transformation of Monads

newtype Eval a = EvalT ContT (EvalResult Val) (ReaderT Env SIO) (EvalResult a)
data EvalResult a
    = RNormal    !a
    | RException !Val

Unrolled Monad.

newtype Eval a = Eval (Env -> (a -> SIO Val) -> (Val -> SIO Val) -> SIO Val)
newtype EvalResult a = RException Val

Benchmarks

% time pugs -e 'my $i=0; for (1..5_000) { $i++ }; say $i'
5000
pugs  0.23s user 0.01s system 98% cpu 0.239 total
% time pugs-patched -e 'my $i=0; for (1..5_000) { $i++ }; say $i'
5000
pugs-patched  0.20s user 0.01s system 98% cpu 0.206 total
% time perl6 -e 'my $i=0; for (1..5_000) { $i++ }; say $i'
5000
perl6  0.22s user 0.03s system 98% cpu 0.259 total

More Benchmarks

% time pugs -e 'my $i=0; for (1..10_000) { $i++ }; say $i'
10000
pugs  0.40s user 0.01s system 99% cpu 0.416 total
% time pugs-patched -e 'my $i=0; for (1..10_000) { $i++ }; say $i'
10000
pugs-patched  0.36s user 0.01s system 99% cpu 0.368 total
% time perl6 -e 'my $i=0; for (1..10_000) { $i++ }; say $i'
10000
perl6  0.23s user 0.03s system 99% cpu 0.263 total

50ms and died …

A reuse of Pugs

  • An implementation of a language similar to Perl6
  • Presented at YAPC Asia 2010
  • It’s called Werl

Werl specification

Wugs

A reference implementations of Werl6

How to install Wugs

A reference implementations of Werl6

$ git clone git@github.com:hiratara/Pugs.hs.git
$ cd Pugs.hs
$ git checkout origin/wugs
$ stack build --install-ghc
$ stack exec -- wugs
% stack exec -- wugs
 __      __                         (W)erl 6
/  \    /  \__ __  ____  ______     (U)ser's
\   \/\/   /  |  \/ ___\/  ___/     (G)olfing
 \        /|  |  / /_/  >___ \      (S)ystem
  \__/\  / |____/\___  /____  >          Version: 6.2.13.dev
       \/       /_____/     \/   Copyright 2005-2015, The Wugs Contributors
--------------------------------------------------------------------

Welcome to Wugs -- Werl6 User's Golfing System
Type :h for help.

Loading Prelude... done.
wugs> wwwWw 1 .. 80 -> $wW { WWwwWW wwWWWW > .5 ?? 'W' !! 'w' }; wWWWw
WWWwwWWWwWwwwWwWwWWWWwWWWwwwwwwWwwWwwWWWwWWwwwwWWWwWWwWwWWwwWWwwwWwWwwwWwwwWWwWw
Bool::True

Werl5 and Werl6

Werl5

Wwwww wwww_wwww {
      WWW $w_w = WWwWWW;
      WWW $w_ww = WWwWWW;
      wWW ($w_w >= $w_ww) {
            wwWwWWw $w_w;
      } WWwWW {
            wwWwWWw $w_ww;
      }
}

wwWwWww wwww_wwww(10,20),"\n";

Werl5 and Werl6

Werl6 is more readable

Wwwww wwww_wwww (WWW $w_w, WWW $w_ww){
      wWW ($w_w >= $w_ww) {
            wwWwWWw $w_w;
      } WWwWW {
            wwWwWWw $w_ww;
      }
}

wWWWw wwww_wwww(10,20);

Inside of Wugs

The map of reserved words

+werl6perl6 :: [(String, String)]
+werl6perl6 =
+  [ ("w", "m")
+  , ("W", "q")
+  , ("ww", "s")
+  , ("wW", "x")
+  , ("Ww", "y")
+  , ("WW", "do")
+  , ("www", "eq")
+  , ("wwW", "ge")
+  , ("wWw", "gt")
+  , ("wWW", "if")
+  , ("Www", "lc")
+  , ("WwW", "le")
+  , ("WWw", "lt")
+  , ("WWW", "my")

Inside of Wugs

Parse both Perl6 and Werl6 reserved words

 symbol :: String -> RuleParser String
 -symbol s = try $ do
 +symbol s = case perl6ToWerl6 s of
 +  Nothing -> symbol' s
 +  Just w -> do ret <- symbol' s <|> symbol' w
 +               return $ case werl6ToPerl6 ret of
 +                 Nothing -> ret
 +                 Just p -> p

-O \(fun\)