Skip to content

Instantly share code, notes, and snippets.

@shouichi
Created February 23, 2012 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shouichi/1895622 to your computer and use it in GitHub Desktop.
Save shouichi/1895622 to your computer and use it in GitHub Desktop.
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: graphviz version 2.26.3 (20100126.1600)
%%Title: Simplified
%%Pages: 1
%%BoundingBox: 36 36 532 378
%%EndComments
save
%%BeginProlog
/DotDict 200 dict def
DotDict begin
/setupLatin1 {
mark
/EncodingVector 256 array def
EncodingVector 0
ISOLatin1Encoding 0 255 getinterval putinterval
EncodingVector 45 /hyphen put
% Set up ISO Latin 1 character encoding
/starnetISO {
dup dup findfont dup length dict begin
{ 1 index /FID ne { def }{ pop pop } ifelse
} forall
/Encoding EncodingVector def
currentdict end definefont
} def
/Times-Roman starnetISO def
/Times-Italic starnetISO def
/Times-Bold starnetISO def
/Times-BoldItalic starnetISO def
/Helvetica starnetISO def
/Helvetica-Oblique starnetISO def
/Helvetica-Bold starnetISO def
/Helvetica-BoldOblique starnetISO def
/Courier starnetISO def
/Courier-Oblique starnetISO def
/Courier-Bold starnetISO def
/Courier-BoldOblique starnetISO def
cleartomark
} bind def
%%BeginResource: procset graphviz 0 0
/coord-font-family /Times-Roman def
/default-font-family /Times-Roman def
/coordfont coord-font-family findfont 8 scalefont def
/InvScaleFactor 1.0 def
/set_scale {
dup 1 exch div /InvScaleFactor exch def
scale
} bind def
% styles
/solid { [] 0 setdash } bind def
/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
/bold { 2 setlinewidth } bind def
/filled { } bind def
/unfilled { } bind def
/rounded { } bind def
/diagonals { } bind def
% hooks for setting color
/nodecolor { sethsbcolor } bind def
/edgecolor { sethsbcolor } bind def
/graphcolor { sethsbcolor } bind def
/nopcolor {pop pop pop} bind def
/beginpage { % i j npages
/npages exch def
/j exch def
/i exch def
/str 10 string def
npages 1 gt {
gsave
coordfont setfont
0 0 moveto
(\() show i str cvs show (,) show j str cvs show (\)) show
grestore
} if
} bind def
/set_font {
findfont exch
scalefont setfont
} def
% draw text fitted to its expected width
/alignedtext { % width text
/text exch def
/width exch def
gsave
width 0 gt {
[] 0 setdash
text stringwidth pop width exch sub text length div 0 text ashow
} if
grestore
} def
/boxprim { % xcorner ycorner xsize ysize
4 2 roll
moveto
2 copy
exch 0 rlineto
0 exch rlineto
pop neg 0 rlineto
closepath
} bind def
/ellipse_path {
/ry exch def
/rx exch def
/y exch def
/x exch def
matrix currentmatrix
newpath
x y translate
rx ry scale
0 0 1 0 360 arc
setmatrix
} bind def
/endpage { showpage } bind def
/showpage { } def
/layercolorseq
[ % layer color sequence - darkest to lightest
[0 0 0]
[.2 .8 .8]
[.4 .8 .8]
[.6 .8 .8]
[.8 .8 .8]
]
def
/layerlen layercolorseq length def
/setlayer {/maxlayer exch def /curlayer exch def
layercolorseq curlayer 1 sub layerlen mod get
aload pop sethsbcolor
/nodecolor {nopcolor} def
/edgecolor {nopcolor} def
/graphcolor {nopcolor} def
} bind def
/onlayer { curlayer ne {invis} if } def
/onlayers {
/myupper exch def
/mylower exch def
curlayer mylower lt
curlayer myupper gt
or
{invis} if
} def
/curlayer 0 def
%%EndResource
%%EndProlog
%%BeginSetup
14 default-font-family set_font
1 setmiterlimit
% /arrowlength 10 def
% /arrowwidth 5 def
% make sure pdfmark is harmless for PS-interpreters other than Distiller
/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
% make '<<' and '>>' safe on PS Level 1 devices
/languagelevel where {pop languagelevel}{1} ifelse
2 lt {
userdict (<<) cvn ([) cvn load put
userdict (>>) cvn ([) cvn load put
} if
%%EndSetup
setupLatin1
%%Page: 1 1
%%PageBoundingBox: 36 36 532 378
%%PageOrientation: Portrait
0 0 1 beginpage
gsave
36 36 496 342 boxprim clip newpath
1 1 set_scale 0 rotate 40 41 translate
% For1
gsave
1 setlinewidth
0 0 0 nodecolor
379 315 27 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
369.5 311.4 moveto 19 (for) alignedtext
grestore
% If1
gsave
1 setlinewidth
0 0 0 nodecolor
297 241 27 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
292.5 237.4 moveto 9 (if) alignedtext
grestore
% For1->If1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 362.41 300.02 moveto
350.51 289.29 334.31 274.67 321.01 262.67 curveto
stroke
0 0 0 edgecolor
newpath 323.34 260.05 moveto
313.57 255.95 lineto
318.65 265.25 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 323.34 260.05 moveto
313.57 255.95 lineto
318.65 265.25 lineto
closepath stroke
grestore
% Array1
gsave
1 setlinewidth
0 0 0 nodecolor
379 241 36.98 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
360.5 237.4 moveto 37 (array) alignedtext
grestore
% For1->Array1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 379 296.33 moveto
379 288.26 379 278.65 379 269.71 curveto
stroke
0 0 0 edgecolor
newpath 382.5 269.67 moveto
379 259.67 lineto
375.5 269.67 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 382.5 269.67 moveto
379 259.67 lineto
375.5 269.67 lineto
closepath stroke
grestore
% Empty1
gsave
1 setlinewidth
0 0 0 nodecolor
461 241 27 18 ellipse_path stroke
grestore
% For1->Empty1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 395.59 300.02 moveto
407.56 289.22 423.9 274.48 437.25 262.43 curveto
stroke
0 0 0 edgecolor
newpath 439.63 265 moveto
444.71 255.7 lineto
434.94 259.8 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 439.63 265 moveto
444.71 255.7 lineto
434.94 259.8 lineto
closepath stroke
grestore
% For2
gsave
1 setlinewidth
0 0 0 nodecolor
213 167 27 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
203.5 163.4 moveto 19 (for) alignedtext
grestore
% If2
gsave
1 setlinewidth
0 0 0 nodecolor
131 93 27 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
126.5 89.4 moveto 9 (if) alignedtext
grestore
% For2->If2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 196.41 152.02 moveto
184.51 141.29 168.31 126.67 155.01 114.67 curveto
stroke
0 0 0 edgecolor
newpath 157.34 112.05 moveto
147.57 107.95 lineto
152.65 117.25 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 157.34 112.05 moveto
147.57 107.95 lineto
152.65 117.25 lineto
closepath stroke
grestore
% Array2
gsave
1 setlinewidth
0 0 0 nodecolor
213 93 36.98 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
194.5 89.4 moveto 37 (array) alignedtext
grestore
% For2->Array2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 213 148.33 moveto
213 140.26 213 130.65 213 121.71 curveto
stroke
0 0 0 edgecolor
newpath 216.5 121.67 moveto
213 111.67 lineto
209.5 121.67 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 216.5 121.67 moveto
213 111.67 lineto
209.5 121.67 lineto
closepath stroke
grestore
% Empty3
gsave
1 setlinewidth
0 0 0 nodecolor
295 93 27 18 ellipse_path stroke
grestore
% For2->Empty3
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 229.59 152.02 moveto
241.56 141.22 257.9 126.48 271.25 114.43 curveto
stroke
0 0 0 edgecolor
newpath 273.63 117 moveto
278.71 107.7 lineto
268.94 111.8 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 273.63 117 moveto
278.71 107.7 lineto
268.94 111.8 lineto
closepath stroke
grestore
% If1->For2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 280.4 226.38 moveto
268.17 215.61 251.34 200.78 237.55 188.63 curveto
stroke
0 0 0 edgecolor
newpath 239.67 185.83 moveto
229.85 181.84 lineto
235.04 191.08 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 239.67 185.83 moveto
229.85 181.84 lineto
235.04 191.08 lineto
closepath stroke
grestore
% Guard1
gsave
1 setlinewidth
0 0 0 nodecolor
297 167 39.1 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
277 163.4 moveto 40 (guard) alignedtext
grestore
% If1->Guard1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 297 222.33 moveto
297 214.26 297 204.65 297 195.71 curveto
stroke
0 0 0 edgecolor
newpath 300.5 195.67 moveto
297 185.67 lineto
293.5 195.67 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 300.5 195.67 moveto
297 185.67 lineto
293.5 195.67 lineto
closepath stroke
grestore
% Empty2
gsave
1 setlinewidth
0 0 0 nodecolor
381 167 27 18 ellipse_path stroke
grestore
% If1->Empty2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 313.6 226.38 moveto
325.91 215.54 342.88 200.58 356.71 188.39 curveto
stroke
0 0 0 edgecolor
newpath 359.25 190.83 moveto
364.44 181.59 lineto
354.62 185.57 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 359.25 190.83 moveto
364.44 181.59 lineto
354.62 185.57 lineto
closepath stroke
grestore
% Guard2
gsave
1 setlinewidth
0 0 0 nodecolor
39 19 39.1 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
19 15.4 moveto 40 (guard) alignedtext
grestore
% If2->Guard2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 113.26 78.73 moveto
100.13 68.17 81.99 53.58 66.92 41.46 curveto
stroke
0 0 0 edgecolor
newpath 68.91 38.56 moveto
58.92 35.02 lineto
64.52 44.02 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 68.91 38.56 moveto
58.92 35.02 lineto
64.52 44.02 lineto
closepath stroke
grestore
% Body
gsave
1 setlinewidth
0 0 0 nodecolor
131 19 34.86 18.38 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
114 15.4 moveto 34 (body) alignedtext
grestore
% If2->Body
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 131 74.33 moveto
131 66.26 131 56.65 131 47.71 curveto
stroke
0 0 0 edgecolor
newpath 134.5 47.67 moveto
131 37.67 lineto
127.5 47.67 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 134.5 47.67 moveto
131 37.67 lineto
127.5 47.67 lineto
closepath stroke
grestore
% Empty4
gsave
1 setlinewidth
0 0 0 nodecolor
211 19 27 18 ellipse_path stroke
grestore
% If2->Empty4
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 147.19 78.02 moveto
158.76 67.32 174.51 52.76 187.46 40.77 curveto
stroke
0 0 0 edgecolor
newpath 190.14 43.06 moveto
195.11 33.7 lineto
185.39 37.92 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 190.14 43.06 moveto
195.11 33.7 lineto
185.39 37.92 lineto
closepath stroke
grestore
endpage
showpage
grestore
%%PageTrailer
%%EndPage: 1
%%Trailer
end
restore
%%EOF
all: report.tex
nkf -j report.tex > report.tex.jis
platex report.tex.jis
dvipdfmx *.dvi
gnome-open report.tex.pdf
\documentclass{jarticle}
\usepackage{graphicx}
\usepackage{url}
\usepackage{amsmath, amssymb}
\usepackage{listings}
\usepackage{color}
\lstset{%
frame={tb}
}%
\title{プログラミングシステム論IIレポート}
\author{48-116109 コンピュータ科学専攻 神谷翔一}
\date{\today}
\begin{document}
\maketitle
\section*{序論}
今回私はRubyのfor文を拡張した。for文はeachに比べて新しくscopeを導入しないので意
図せずに外部の変数を破壊してしまう恐れがあると言う理由からあまり使われていない
様に思われる。しかし、言語において予約後は非常に貴重な物なので遊ばせておくのは
勿体無い。そこでfor文を拡張し以下 (Listing \ref{extended-for}) の様にguard付き
の多重loopを書けるようにした。これは以下のコード (Listing \ref{original-for})
と同等である。
\begin{lstlisting}[label=extended-for, caption=拡張for文]
for i in [1,2,3,4] when i % 2 == 0
j in [5,6,7,8] when j % 2 == 0
puts "#{i}, #{j}"
end
\end{lstlisting}
\begin{lstlisting}[label=original-for, caption=拡張for文と同等のコード]
for i in [1,2,3,4]
if i % 2 == 0
for j in [5,6,7,8]
if j % 2 == 0
puts "#{i}, #{j}"
end
end
end
end
\end{lstlisting}
以上の様に拡張for文を使うことでguard付きの多重loopが簡潔に記述出来る。以上の
拡張for文は元々のfor文が使える場所全てで使用出来、かつ条件が簡潔なときはfor文
の中にguardとして埋め込めるので、多様な場合に適用可能である。以下 (Listing
\ref{practical-example}) は拡張for文の実用的な例である。(全ての会員の中から
管理者を取得し、その管理者の記事で未公開かつ二ヶ月以上前の物を全て削除する。)
\begin{lstlisting}[label=practical-example, caption=拡張for文の実用的な例]
for user in User.all when user.admin?
for article in user.articles when article.not_published &&
article.created_at < 2.month.ago
article.destroy!
end
end
\end{lstlisting}
\section*{設計と実装}
拡張for文を実現する為には Listing \ref{extended-for} を受け取り Listing
\ref{original-for}に変換してやれば良い。これは抽象構文木を構築するときに行う
のが簡単である。従ってparse.yを一部変更した。実装の大枠は下記 Listing
\ref{parse.y}。
\begin{lstlisting}[label=parse.y, caption=parse.y]
primary : k_for
文s
k_end
{
$$ = $2;
}
loops : for_var keyword_in expr_value
keyword_when expr_value term
compstmt
{
scope = NEW_NODE(NODE_SCOPE,
table, NEW_IF(cond($5), $7, 0), args);
$$ = NEW_FOR(0, $3, scope);
}
| for_var keyword_in expr_value
keyword_when expr_value term
文s
{
// 上と同じ。
}
\end{lstlisting}
これにより下図\ref{fig:ast}の様な抽象構文木が得られる。
\begin{figure}[htbp]
\begin{center}
\includegraphics[width=100mm]{ast.eps}
\end{center}
\caption{拡張for文が展開されて出来た抽象構文木}
\label{fig:ast}
\end{figure}
\section*{評価}
拡張for文は純粋にforを拡張した物なので適用範囲は非常に広い。又、簡単な
条件文をguardとしてfor文に埋め込めるのでコードが簡潔になる事が利点として
挙げられる。欠点としては元来のfor文のscopeを導入しないと言う欠点をそのまま
受け継いでいる。その為使用に当っては変数を破壊しない様に注意が必要である。
新しくscopeを導入するのは次の課題としたい。以上のソースコードは\url{
https://github.com/shouichi/ruby}に上げてある。
\section*{宿題}
宿題として以上の拡張for文をRuby-Coreに提案した
(\url{https://bugs.ruby-lang.org/issues/6073}) 。
その結果、本レポートで挙げたguard付きの多重loopだけでなく、
Scalaと同等の機能を実装してはどうかと言う意見が上がった。
Scalaのfor文はリスト内包表記と同等の機能がある。
リスト内包記法はHaskell, Pythonにも実装されていて、有要だと考えられている。
\newpage
\begin{lstlisting}[label=scala-for, caption=Scalaのfor文]
for (i <- List(1,2); j <- List(3,4))
yield (i, j)
// => List((1,3), (1,4), (2,3), (2,4))
\end{lstlisting}
これは以下のコードと同値である。
\begin{lstlisting}[label=flat-map, caption=Listing \ref{scala-for}と同等のコード]
[1,2].flat_map { |i| [3,4].map { |j| [i,j] } }
# => [[1, 3], [1, 4], [2, 3], [2, 4]]
\end{lstlisting}
上記のfor文のコードはflat\_map/mapのコードと比べて簡潔になっているのが分かる。
guardも書く事が出来るので、何重ものmap/flat\_mapをchainさせるよりも可読性
が上がる事が分かる。
リスト内包記法をRubyで実現する為に以下の様な文法を想定している。
\begin{lstlisting}[label=flat-map-for, caption=Rubyでリスト内包記法]
for yield i in [1,2], j in [3,4]
[i, j]
# => [[1, 3], [1, 4], [2, 3], [2, 4]]
\end{lstlisting}
forの直後にyieldがあるのはRubyではblockを呼ぶ時にyieldを使う為forの中に
yieldを置くと、forのyieldとblock callのyieldが区別出来なくなるからである。
しかし、この文法はややこしいのでより良い文法を模索している。
\begin{thebibliography}{}
\bibitem{iloveruby}
\emph{Rubyソースコード完全解説}
\url{http://i.loveruby.net/ja/rhg/book/}
\end{thebibliography}
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment