PugsPerl 6 on Haskell
AudreyTang1
Pugs...
≝ Perl6Compiler
≝ Perl6Runtime
≝ Perl6TestSuite
3
Perl6Code
✓ 119Modules
✓ 145Examples
✓ 11,550UnitTests
9
• use v6-pugs;• use perl5:DBI;• use perl5:Encode;• use perl5:Template;• # ...
Perl5
12
Parrot
Parrot
Tcl Python Scheme
Pugs
13
Haskell
• inline Haskell => q[• fac :: Int -> Int• fac 0 = 1• fac x = x * fac (x - 1)• ];
14
PugsIntermediateLanguage
17
PILBackends
⇛ Perl5
⇛ Parrot
⇛ JavaScript
18
6.0InitialRelease
䷁
21
6.2Functions
䷗
22
6.283Grammar
䷊
24
6.2831TypeSystem
䷡
25
6.28318Macros
䷪
26
6.283185SelfHosting
䷀
27
“FrivolousToyinterpreter”(asseenon/.)
30
“FrivolousToyinterpreter”
31
“FrivolousToyinterpreter”
32
“Toyinterpreter”
33
“Toyinterpreter”
34
Arrowlength
Time
10000+commits
200+committers
38
TestDriven
☺Bugreport➟Test
☺SmokeServer
☺:todo<unspecced>
39
Anarchistic
☺20+Sub‐projects
☺10+Languages
☺ConstantReview
40
PatchesWelcome!
41
CommitsWelcome!
42
irc.freenode.net#perl6
44
λCamels✆ 100+People✆ 20+Regulars✆ TimToady✆ obra,leo,chip,pmichaud✆ rgs,ko1,why,xerox...
45
MailingLists✆ perl6‐language
✆ perl6‐internals
✆ perl6‐compiler
✆ perl6‐users
50
PlanetSix
✆ pugs.blogs.com
✆ perlsoc2006.blogspot.com
✆ Listsummaries
51
...andallthoseWikis
52
http://svn.openfoundry.org/pugs/
http://perlcabal.org/~audreyt/darcs/pugs/
SVK
Repositories
54
SVK♜ OfflineBranches
♜ IncrementalMerge
♜ Client‐only:Fast!
♜ Perl6Ready
55
Hackathon♨ Taipei
♨ Vienna
♨ Toronto
♨ Amsterdam
♨ Echt
♨ Lismore
♨ Mt.Arbel
♨ Vienna2
♨ Tokyo
♨ Redmond
♨ Chicago
♨ Boston
♨ Portland
♨ ...andmore!
58
Erdösing♨ 2006..∞
59
Abstractions➥Sexy
71
Closuressubmake_counter{my$start=shift;returnsub{++$start};}my$from_ten=make_counter(10);my$from_three=make_counter(3);print$from_three‐>();#4print$from_three‐>();#5print$from_ten‐>();#11
72
TieuseTie::Google;tiemy%search=>'Tie::Google','~/.googlekey';
for(@{$search{perl}}){print"*$_‐>{title}‐$_‐>{URL}\n";}
73
Abstractions
∀ bless()
∀ IOLayers
∀ BEGIN{...}
74
Shorthands➥Natural
76
Shorthands
ℑ Regex
ℑ Context
ℑ Topical$_
77
Nocoding➥bestcoding
79
♡ 10+years
♡ 5000+authors
♡ 10000+modules
CPAN
81
♡ PackageManagement
♡ Rating&Discussion
♡ SmokeTesting
♡ IssueTracking
Services
82
Vocabulary≩Syntax
83
“BestthinghappenedtoPerl”
84
Perl5isn'tthebestthing
forCPAN
86
SyntaxRedundancy
☣
88
• usev5;• subrender{• my$self=shift;• my%opts=(x=>1,y=>1,z=>0,@_);• formy$item($self‐>filter(@{$self‐>{_items}})){• print$item‐>draw(• x=>$opts{x},• y=>$opts{y},• z=>$opts{z},• ),"\n";• }• }
89
• usev6‐pugs;• methodrender($x=1,$y=1,$z=0){• [email protected](@.items){• say.draw(:$x,:$y,:$z);• }• }•
90
JengaInternals☣
91
Bug‐for‐bugcompatibility
☣
93
BestPracticetakesdiscipline
94
BestPracticeshouldbeNatural!
96
2002Apocalypses
100
2004Synopses
102
Pugs has been…
105
Feb1TaPLarrived
asanexercise…
106
Feb6PrimitiveInterpreter
(1|2)+(3|4)➥(4|5|6)
107
Feb16ImperativeRuntime
say"Hello,world"
108
Mar19PCRERegex
s:P5:g/5/6/;
110
Apr26BEGINblocks
useCGI;111
May8svnbot.p6
r2851|iblech++
112
May5EmbeddedParrot
AddHandlermod_pugs
113
May25Prelude.pm
subsprintf($fmt,*@args)
114
May29EmbeddedPerl5
useperl5:DBI;115
Jun2evalbot.p6
[#perl6]?eval1+1
117
Jun24Perl6→PIL→Parrot
makesmoke‐pir118
Jul14PIL→Perl5
makesmoke‐perl5
119
Jul17PIL→JavaScript
makesmoke‐js
120
Aug1Self‐hostingObjectModel
classClassisObject;
121
Aug3KontentWiki
useperl5:Template;
122
Oct9HaskellCabalSupport
libPugs.a124
Nov2ndRuntimeAPISpec
Perl6::ObjectSpace
125
Nov3ConcurrencySpec
subfisthrottled(:limit(3)){…}
126
Nov4PackagingSpec
p5‐Foo‐1.0‐cpan+KANE.jib
127
Nov7Coroutines
coro{yield}
128
Nov231stcommitfromLarry(stillwaitingforGuido☺)
129
Dec20LexicalImport
{useModule;…}
131
Jan6YAMLSerialization
say$x.yaml;132
Jan16Pugs/ParrotRuns!
parrotIsBrokenXXX=False
133
Feb3Self‐parsingGrammar
grammarGrammar;134
Feb14RulesengineinPerl5
Pugs::Compiler::Rule
135
Feb22LarryJoins#perl6
<fglock>TimToady:welcome<Juerd>Justtrytonotgetaddicted:)<TimToady>Juerd:toolate…
136
Feb24Perl6::DocTreeOverview/Tutorial
FAQ/Perl5/Spec/API
137
Feb25CodeDOM
$ast=q:code/say"hi"/;
138
Mar11Perl5Runtimeusev6‐pugs;
140
Mar15DocDOMSpec
=insertCopyright.kwid
141
Mar16BootstrappedonPerl5
lrep.p6lrep.p6
142
Apr1CallingConventionSpec
$tree=\($obj:attr=>1,$child);
143
Apr3UnicodeSpec
=encodingBig5
144
Apr21MITLicense
145
May8PredictiveParsing
<TimToady>"do,ordonot.thereisnotry..."
146
May20HsSyck+ByteString
“makesmoke”➥14minutes
147
June1SummerofCode
149
SoC:Perl.org
☼ CompletePerl5ParserandPerl6Output
☼ Perl6DBIModule
☼ PugsSelf‐hostingBootstrapFromPerl5andRules
☼ SoftwareTransactionalMemoryforParrot
150
SoC:Haskell.org
☼ FastMutableCollectionTypesforHaskell
☼ UnicodeByteString,Data.Rope,GenericParsec
151
June4SoftwareTransactionalMemory
atomically{...}
152
June6ImportfromEmbeddedPerl5
useperl5:Digest::MD5<md5_hex>;
153
TodayPugs6.2.12
154
ParrotRoadmap
Parrot
Tcl Python Scheme
156
ParrotRoadmap
Parrot
Tcl Python Scheme
Perl 5(Ponie)
Perl 6
157
PugsRoadmap
Pugs
JavaScript
Haskell Perl 5
158
Pugs
JavaScript
Haskell Perl 5
YARV?JVM?
CLR? PyPy?
PugsRoadmap
159
PopularObjectLanguage
161
GeneratingJSژ Java:GoogleWebToolkit
ژ Perl:Jifty
ژ Ruby:Rails/JS
ژ Python:Pyjamas
ژ C#:Script#
162
Samelanguageforbothsides
✓163
Client‐sidejustatinysubset
✗164
CompilingtoJS
ژ HOP/Scheme2JS
ژ Links
ژ HaXe
ژ Pugs!
165
pugs‐BJS
• WritteninPerl5
• Passes90%oftests
• ~30kRuntime
167
PIL2JSRuntime
• Primitives&Autoboxing
• Meta‐objectprotocol
• SupportsJSANlibraries
168
JSAN
• "CPAN".replace(/CP/,"JS")
• ModulesystemwithPrototype.js
• Test.Simple,Jemplate,etc.
169
Shortcomings
• Callingconventiontoocomplex
• CPSrunloopisslow
• Notailrecursionnorgoto
• Butthere'shope!
170
JS2.0
• Selfhosting
• BacktranslatetoJS1
• Types,Modules,Continuations
• PartofFirefox3.0(nextyear)
171
“CPANisthelanguagePerlisjustsyntax”
173
YAML
• TaggedGraphs
• PerfectforASTs
• Syck:CbindingsfromRuby
177
Inline.pm
• Reuseotherlanguage'slibraries
• SpiderMonkeyallowsJSAN+DBI
• ...butnotforProduction
178
Production
• Existingcode
• NoGHC/SpiderMonkey/Parrot
• NoRewrite‐from‐scratch
• RunningonPerl5VM
179
Perl5VM
• Activelydeveloped
• Widelydeployed
• JustneedaPerl6runtime
180
ObjectsWithClass
182
• usev6‐pugs;• classPoint;• • • has$.xisrw;#instanceattributes• has$.y;#default"isreadonly"• • methodclear(){• • • $.x=0;#accessiblewithintheclass• $.y=0;• }•
183
• usev5;• packagePoint;• useMoose;• • hasx=>(is=>'rw');• hasy=>(is=>'ro');• • subclear{• my$self=shift;• • $self‐>{x}=0;• $self‐>y(0);• }•
184
• usev6‐pugs;• classPoint3D;• • • isPoint;• • has$.z;• • methodclear(){• • call;• $.z=0;• };•
186
• usev5;• packagePoint3D;• useMoose;• • extends'Point';• • hasz=>(isa=>'Int');• • overrideclear=>sub{• my$self=shift;• super;• $self‐>{z}=0;• };•
187
• usev5;• packagePoint3D;• useMoose;• • extends'Point';• • hasz=>(isa=>'Int');• • afterclear=>sub{• my$self=shift;• • $self‐>{z}=0;• };•
188
• usev6‐pugs;• classAddress;• useperl5:Locale::US;• useperl5:Regexp::Common<zip$RE>;• • my$STATES=Locale::US.new;• subsetUS_StateofStrwhere{• $STATES{any(<code2statestate2code>)}{.uc};• };• • hasUS_State$.stateisrw;• hasStr$.zip_codeisrwwhere{• $_~~$RE<zip><<US>{'‐extended'=>'allow'}• };•
190
• usev5;• packageAddress;• useMoose;• useMoose::Util::TypeConstraints;• useLocale::US;• useRegexp::Common'zip';• • my$STATES=Locale::US‐>new;• subtypeUSState=>asStr=>where{• $STATES‐>{code2state}{uc($_)}• or$STATES‐>{state2code}{uc($_)};• }• • hasstate=>(is=>'rw',isa=>'USState');• haszip_code=>(• is=>'rw',• isa=>subtypeStr=>where{• /$RE{zip}{US}{‐extended=>'allow'}/• },• );•
191
• usev6‐pugs;• classBinaryTreeisrw;• • hasAny$.node;• hasBinaryTree$.parenthandles{• parent_node=>'node'• };• hasBinaryTree$.left={• lazy{BinaryTree.new(parent=>self)}• };• hasBinaryTree$.right={• lazy{BinaryTree.new(parent=>self)}• };•
193
• usev5;• packageBinaryTree;• useMoose;• • hasnode=>(is=>'rw',isa=>'Any');• hasparent=>(• is=>'rw',• isa=>'BinaryTree',• handles=>{parent_node=>'node'},• weak_ref=>1,• );• hasleft=>(• is=>'rw',• isa=>'BinaryTree',• default=>sub{BinaryTree‐>new(parent=>$_[0])},• lazy=>1,• );
• #dittofor“hasright”
194
•Roles
•Coercion
•Metaclasses
Morefeatures
195
Pugs::Compiler::Rule╬
196
RegexObjects
197
• usev6‐pugs;
• my$txt='Car=ModelT,1909';• my$pat=rx{• Car‐• [(Ferrari)• |(ModelT,(\d\d\d\d))• ]• };• $txt~~$paterrfail"Cannotmatch";•
198
• usev5;• usePugs::Compiler::Regex;• my$txt='Car=ModelT,1909';• my$pat=Pugs::Compiler::Regex‐>compile(q(• Car‐• [(Ferrari)• |(ModelT,(\d\d\d\d))• ]• ));• $pat‐>match($txt)ordie"Cannotmatch";•
199
MatchObjects
200
• usev6‐pugs;
• my$pat=rx{• Car=[• (Ferrari)|(ModelT,(\d\d\d\d))• ]• };• • my$match=('Car=ModelT,1909'~~$pat);• say$match;#"Car=ModelT,1909"• say$match[0];#undef• say$match[1];#"ModelT,1909"• say$match[1][1];#"1909"• say$match[1][1].from;#11• say$match[1][1].to;#15•
201
• usev5;• usePugs::Compiler::Regex;• my$pat=Pugs::Compiler::Regex‐>compile(q(• Car=[• (Ferrari)|(ModelT,(\d\d\d\d))• ]• ));• usefeatureqw(say);• my$match=$pat‐>match('Car=ModelT,1909');• say$match;#"Car=ModelT,1909"• say$match‐>[0];#undef• say$match‐>[1];#"ModelT,1909"• say$match‐>[1][1];#"1909"• say$match‐>[1][1]‐>from;#11• say$match‐>[1][1]‐>to;#15•
202
NamedCaptures
203
• usev6‐pugs;• • my$pat=rx{• Car=[• (Ferrari)• |(ModelT,$<year>:=[\d\d\d\d])• ]• };
• my$match=('Car=ModelT,1909'~~$pat);• say$match;#"Car=ModelT,1909"• say$match[1];#"ModelT,1909"• say$match[1]<year>;#"1909"• say$match[1]<year>.from;#11• say$match[1]<year>.to;#15•
204
• usev5;• usePugs::Compiler::Regex;• my$pat=Pugs::Compiler::Regex‐>compile(q(• Car=[• (Ferrari)• |(ModelT,$<year>:=[\d\d\d\d])• ]• ));• usefeatureqw(say);• my$match=$pat‐>match('Car=ModelT,1909');• say$match;#"Car=ModelT,1909"• say$match‐>[1];#"ModelT,1909"• say$match‐>[1]{year};#"1909"• say$match‐>[1]{year}‐>from;#11• say$match‐>[1]{year}‐>to;#15•
205
GrammarModules
206
• usev6‐pugs;• • grammarCarInfo;• • regexcar{• Car=[(Ferrari)|(ModelT,<year>)]• }• regexyear{• \d\d\d\d• }• • moduleMain;• my$match=('Car=ModelT,1909'~~CarInfo.car);•
207
• usev5;• usePugs::Compiler::Regex;• packageCarInfo;• usebase'Pugs::Grammar::Base';• *car=Pugs::Compiler::Regex‐>compile(q(• Car=[(Ferrari)|(ModelT,<year>)]• ))‐>code;• *year=Pugs::Compiler::Regex‐>compile(q(• \d\d\d\d• ))‐>code;• • packagemain;• my$match=CarInfo‐>car('Car=ModelT,1909');•
208
ResultObjects
209
• #TypicalPerl5code• usev5;• my$txt='Car=ModelT,1909';• my$pat=qr{• Car=(?:(Ferrari)|(ModelT,(\d\d\d\d)))• }x;• my$obj;• if($txt=~$pat){• if($1){• $obj=Car‐>new(color=>"red");• }elsif($2){• $obj=Car‐>new(color=>"black",year=>$3);• }• }•
210
• usev6‐pugs;
• my$txt='Car=ModelT,1909';• my$pat=rx{• Car=[Ferrari• {returnCar.new(:color<red>)}• |ModelT,$<year>:=[\d\d\d\d]• {returnCar.new(:color<black>:$<year>)}• ]• };
• my$obj=$($txt~~$pat);• print$obj<year>;#1909
211
• usev5;• usePugs::Compiler::Regex;• my$txt='Car=ModelT,1909';• my$pat=Pugs::Compiler::Regex‐>compile(q(• Car=[Ferrari• {returnCar‐>new(color=>'red')}• |ModelT,$<year>:=[\d\d\d\d]• {returnCar‐>new(• color=>'black',year=>$<year>)}• ]• ));• my$obj=$pat‐>match($txt)‐>();• print$obj‐>{year};#1909
212
Module::Compile§
213
SourceFilter
214
• usev5;• useFilter::Simplesub{• s{(^sub\s+\w+\s+\{)}• {$1\nmy$self=shift;\n}mgx;• }•
215
•Addsdependency
•Slowsdownstartup
•Breaksperl‐d
•WrecksotherSourceFilters
Filter::SimpleBad
216
• usev5;• useFilter::Simplesub{• s{(^sub\s+\w+\s+\{)}• {$1\nmy$self=shift;\n}mgx;• }
218
• usev5;• useFilter::Simple::Compilesub{• s{(^sub\s+\w+\s+\{)}• {$1\nmy$self=shift;\n}mgx;• }
219
Howdoesitwork?
220
Little‐knownfact:
221
“useFoo”looksforFoo.pmcbeforeFoo.pm
222
• %echo'print"Hello\n"'>Foo.pmc• %perl‐MFoo‐e1• Hello
223
Savefilteredresultto.pmc...
224
...nofilteringneedednexttime!
225
•Freeofuser‐sidedependencies
•Faststartuptime
•Debuggablesourceisallin.pmc
•Allowscomposableprecompilers
Module::CompileGood
226
Filter::Simple::Compile
227
• #Drop‐inreplacementtoFilter::Simple• packageAcme::Y2K;• useFilter::Simple::Compilesub{• tr/y/k/;• }•
228
• #It'slexical!• {• useAcme::Y2K;• pacyageFoo;• mydir"tmp";• }• my$normal_code_here;•
229
Filter::Macro
230
• packageMyHandyModules;• useFilter::Macro;• #linesbelowwillbeexpandedintocaller'scode• usestrict;• usewarnings;• useFatalqw(openclose);• useFindBinqw($Bin);•
231
• #Inyourcode• packageMyApp;• useMyHandyModules;• print"I'minvokedfrom$Bin";•
232
Nodependencyon
MyHandyModules.pm
233
WhataboutDeployingPerl6?
234
Source:Rule.pm
236
• usev6‐pugs;• • grammarPugs::Grammar::Rule;• rulews:P5{• ^((?:\s|\#(?‐s:.)*)+)• }• #...morerules...
237
Target:Rule.pmc
238
• #Generatedfile‐donotedit!• ##################(((32‐bitChecksumValidator)))##################• BEGIN{use5.006;local(*F,$/);($F=__FILE__)=~s!c$!!;open(F)• ordie"Cannotopen$F:$!";binmode(F,':crlf');unpack('%32N*',<F>)• ==0x1D6399E1ordie"Checksumfailedforoutdated.pmcfile:${F}c"}• #####################################################################• packagePugs::Grammar::Rule;• usebase'Pugs::Grammar::Base';• *{'Pugs::Grammar::Rule::ws'}=sub{• my$grammar=shift;• #warn"ruleargumentisundefined"unlessdefined$_[0];• $_[0]=""unlessdefined$_[0];• my$bool=$_[0]=~/^((?:\s|\#(?‐s:.)*)+)(.*)$/sx;• return{• bool=>$bool,• match=>$1,• tail=>$2,• #capture=>$1,• }• };• #...morerules...
239
WritePerl6compiletoPerl5
⇪240
Eclecticism☯
241
Staticvs
Dynamic244
•usev5;•subf{•sqrt($_[0]**2+$_[1]**2)•}•my$five=f(3,4);
245
•usev6‐pugs;•subf{•sqrt(@_[0]**2+@_[1]**2)•}•my$five=f(3,4);
246
OptionalAnnotations
247
• subf(Num$x,Num$y){• sqrt($x**2+$y**2);• }• myNum$five=f(3,4);
•
248
HybridTypeChecking
249
• subsetPositiveofNumwhere{$_>0}
• subf(• Positive$x,Positive$y• ‐‐>Positivewhere{$_>=($x&$y)}• ){• sqrt($x**2+$y**2);• }
• my$five:=f(3,4);#inferredasPositive
•
250
Compilervs
Runtime251
BEGINBlock
• CompilerisaREPL
• Everythingisswappable
• Atendofcompilation,savetheobjectspace
252
ExtensibleGrammar
253
• subpostfix:<!>($x){• [*]1..$x• }• • say10!;#3628800
254
SyntacticMacros
255
• macrocircumfix:</**/>($x)• isparsed/.*?/• {''}• • /*ThisisaC‐stylecomment*/
•
256
Caller‐siteMacros
257
• macrohi(){• q:code(:COMPILING))• {"Hello,$s"}• }• my$s="world";• sayhi;#Hello,world
258
ImplicitGenerators
260
• my@fib:=(• 0,1,• each(@fib;@fib[1..*])• .map(&infix:<+>)• );
261
ExplicitAnnotations
262
• my$ignored=lazy{9**9**9}• my$unused=lazy{say[1..$ignored]}• print"Hello,world!"
263
Classesvs
Prototypes264
• classDogisMammaldoesPet{• my$countwhere0..100;• has$!brain;• has$nameisrw="fido";• has$furhandlesGroomable;• has$tailhandles<waghang>;• has&vocalize=&say;• methodowner()handless/^owner_//{...}• }
•
266
• myDog$fido.=new;• #Dog.isa(Dog);$fido.isa(Dog);• • $fido.meta.add_method(• 'bark',• method(){$.vocalize('Woof!')}• );• #Dog.can('bark');$fido.can('bark');
267
My Languagevs
Your Language268
•usejsan:DOM;•useperl5:DBI;•useparrot:PGE;•usehaskell:Prelude;
269
use Haskell;λ
270
WhyHaskell?
• CodeasSpec
• ExplicitEffects
• Zerorefactoringcost
271
http://perlcabal.org/~audreyt/tokyo/ecs-haskell.xul
272
"Forceyoutoknowwhatyouaredoing."
273
import Perl◉
274
"Bestwhenyoudon'tknowwhatyouaredoing."
275
FastMutableCollection
277
UnicodeLayerOnByteStrings
278
What’s Next?✈
281
UpcomingHackathons
283
YAPC::NAHackathon• “LearningPerl6”
• SpeedupPerl5runtime
• Parrotcallingconvention
• StandardizeMooseMOP
284
BostonHackathon
• Perl6portingexercise
• IntegrateHsJudy
• BenchmarkingRuntimes
285
WhenwillPerl6bereleased?
☾
286
ByChristmas!
287
WhenPerl6isout,everydaywillbelike
Christmas!❆
288