Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I do not have a PhD, nor any other kind of degree neither in CS nor math nor indeed any other field. I have no prior experience with Scala nor any other similar language. I have no experience with even remotely comparable type systems. In fact, the only language that I have more than just a superficial knowledge of which even <em>has</em> a type system is Pascal, not exactly known for its sophisticated type system. (Although it <em>does</em> have range types, which AFAIK pretty much no other language has, but that isn't really relevant here.) The other three languages I know are BASIC, Smalltalk and Ruby, none of which even have a type system.</p> <p>And yet, I have no trouble at all understanding the signature of the <code>map</code> function you posted. It looks to me like pretty much the same signature that <code>map</code> has in every other language I have ever seen. The difference is that this version is more generic. It looks more like a C++ STL thing than, say, Haskell. In particular, it abstracts away from the concrete collection type by only requiring that the argument is <code>IterableLike</code>, and also abstracts away from the concrete return type by only requiring that an implicit conversion function exists which can build <em>something</em> out of that collection of result values. Yes, that is quite complex, but it really is only an expression of the general paradigm of generic programming: do not assume anything that you don't actually have to.</p> <p>In this case, <code>map</code> does not actually <em>need</em> the collection to be a list, or being ordered or being sortable or anything like that. The only thing that <code>map</code> cares about is that it can get access to all elements of the collection, one after the other, but in no particular order. And it does not need to know what the resulting collection is, it only needs to know how to build it. So, that is what its type signature requires.</p> <p>So, instead of</p> <pre><code>map :: (a → b) → [a] → [b] </code></pre> <p>which is the traditional type signature for <code>map</code>, it is generalized to not require a concrete <code>List</code> but rather just an <code>IterableLike</code> data structure</p> <pre><code>map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j </code></pre> <p>which is then further generalized by only requiring that a function exists that can <em>convert</em> the result to whatever data structure the user wants:</p> <pre><code>map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c </code></pre> <p>I admit that the syntax is a bit clunkier, but the semantics are the same. Basically, it starts from </p> <pre><code>def map[B](f: (A) ⇒ B): List[B] </code></pre> <p>which is the traditional signature for <code>map</code>. (Note how due to the object-oriented nature of Scala, the input list parameter vanishes, because it is now the implicit receiver parameter that every method in a single-dispatch OO system has.) Then it generalized from a concrete <code>List</code> to a more general <code>IterableLike</code></p> <pre><code>def map[B](f: (A) ⇒ B): IterableLike[B] </code></pre> <p>Now, it replaces the <code>IterableLike</code> result collection with a function that <em>produces</em>, well, really just about anything.</p> <pre><code>def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That </code></pre> <p>Which I really believe is not <em>that</em> hard to understand. There's really only a couple of intellectual tools you need:</p> <ol> <li>You need to know (roughly) what <code>map</code> is. If you gave <em>only</em> the type signature without the name of the method, I admit, it would be a lot harder to figure out what is going on. But since you already <em>know</em> what <code>map</code> is supposed to do, and you know what its type signature is supposed to be, you can quickly scan the signature and focus on the anomalies, like "why does this <code>map</code> take two functions as arguments, not one?"</li> <li>You need to be able to actually <em>read</em> the type signature. But even if you have never seen Scala before, this should be quite easy, since it really is just a mixture of type syntaxes you already know from other languages: VB.NET uses square brackets for parametric polymorphism, and using an arrow to denote the return type and a colon to separate name and type, is actually the norm.</li> <li>You need to know roughly what generic programming is about. (Which isn't <em>that</em> hard to figure out, since it's basically all spelled out in the name: it's literally just programming in a generic fashion).</li> </ol> <p>None of these three should give any professional or even hobbyist programmer a serious headache. <code>map</code> has been a standard function in pretty much every language designed in the last 50 years, the fact that different languages have different syntax should be obvious to anyone who has designed a website with HTML and CSS and you can't subscribe to an even remotely programming related mailinglist without some annoying C++ fanboy from the church of St. Stepanov explaining the virtues of generic programming.</p> <p>Yes, Scala <em>is</em> complex. Yes, Scala has one of the most sophisticated type systems known to man, rivaling and even surpassing languages like Haskell, Miranda, Clean or Cyclone. But if complexity were an argument against success of a programming language, C++ would have died long ago and we would all be writing Scheme. There are lots of reasons why Scala will very likely not be successful, but the fact that programmers can't be bothered to turn on their brains before sitting down in front of the keyboard is probably not going to be the main one.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload