Skip to content

Tuple.x puzzler #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions puzzlers/pzzlr-tuple-x-puzzler.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<h1>Making a Point</h1>
<table class="table meta-table table-condensed">
<tbody>
<tr>
<td class="header-column"><strong>Contributed by</strong></td>
<td>Tim van Heugten</td>
</tr>
<tr>
<td><strong>Source</strong></td>
<td>N/A</td>
</tr>
<tr>
<td><strong>First tested with Scala version</strong></td>
<td>2.11.6</td>
</tr>
</tbody>
</table>
<div class="code-snippet">
<h3>What is the result of executing the following code?</h3>
<pre class="prettyprint lang-scala">
object TwoD {
case class Point(x: Int, y: Int)
object Point {
def ->(coords: (Int, Int)) = apply(coords._1, coords._2)
}
}

val originMethod = TwoD.Point.->(0.->(0))
val zerooneMethod = TwoD.Point.->(0.->(1))
val originInfix = TwoD.Point -> 0 -> 0
val zerooneInfix = TwoD.Point -> 0 -> 1

println(originMethod.x == zerooneMethod.x)
println(originInfix.x == zerooneInfix.x)
</pre>
<ol>
<li>Prints:
<pre class="prettyprint lang-scala">
true
true
</pre>
</li>
<li id="correct-answer">Prints:
<pre class="prettyprint lang-scala">
true
false
</pre>
</li>
<li>Both <tt>println</tt> statements fail to compile</li>
<li>The first <tt>println</tt> statement prints:
<pre class="prettyprint lang-scala">
true
</pre>
and the second fails to compile
</li>
</ol>
</div>
<button id="show-and-tell" class="btn btn-primary" href="#">Display the correct answer, explanation and comments</button>
<div id="explanation" class="explanation" style="display:none">
<h3>Explanation</h3>
<p>
Since method <tt>-></tt> is a single-argument method, it can be invoked
using <a href="http://docs.scala-lang.org/style/method-invocation.html" target="blank">
infix notation</a> <tt>A -> B</tt>, as well as via the &quot;standard&quot;
Java convention <tt>A.->(B)</tt>. In common with other Scala operators not
ending in a colon <tt>':'</tt> character, it is left-associative (SLS
&sect;6.12.3).
</p>
<p>
As a result, the definitions of <tt>originInfix</tt> and <tt>zerooneInfix
</tt> are parsed as <tt>(TwoD.Point -> 0) -> 0</tt> and
<tt>(TwoD.Point -> 0) -> 1</tt>, respectively. Both values are tuples:
<tt>originInfix</tt> becomes <tt>((TwoD.Point, 0), 0)</tt>;
<tt>zerooneInfix</tt> becomes <tt>((TwoD.Point, 0), 1)</tt>.
</p>
<p>
The expression <tt>originInfix.x == zerooneInfix.x</tt> still compiles,
however, because a value <tt>x</tt> actually is defined (via an implicit
conversion) on <a href="http://www.scala-lang.org/api/current/index.html#scala.Tuple2" target="blank">
<tt>Tuple2</tt></a>. This value is the tuple itself, so <tt>originInfix.x
== zerooneInfix.x</tt> returns false.
</p>
<p>
In the definitions of values <tt>originMethod</tt> and
<tt>zerooneMethod</tt>, the parentheses requires by the standard
&quot;Java-style&quot; method invocation mean that expressions are
parsed as <tt>TwoD.Point -> (0 -> 0)</tt> and <tt>TwoD.Point ->
(0 -> 1)</tt>. The two resulting <tt>Point</tt> instances have the same
x-coordinate, so <tt>originMethod.x == zerooneMethod.x</tt> returns true.
</p>
</div>