Skip to content

Rewrite Currying tour as Multiple Parameter Lists #986

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

Merged
merged 12 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 1 addition & 1 deletion _tour/case-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ partof: scala-tour

num: 11
next-page: pattern-matching
previous-page: currying
previous-page: multiple-parameter-lists
prerequisite-knowledge: classes, basics, mutability

redirect_from: "/tutorials/tour/case-classes.html"
Expand Down
43 changes: 0 additions & 43 deletions _tour/currying.md

This file was deleted.

44 changes: 44 additions & 0 deletions _tour/multiple-parameter-lists.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
layout: tour
title: Multiple Parameter Lists

discourse: true

partof: scala-tour

num: 10
next-page: case-classes
previous-page: nested-functions

redirect_from: "/tutorials/tour/multiple-parameter-lists.html"
---

Methods may define multiple parameter lists. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This is formally known as currying." and then maybe a link to the currying wikipedia page? https://en.wikipedia.org/wiki/Currying

Copy link

@tfinneid tfinneid Jan 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but I would also suggest changing the title to "Multiple Parameter Lists (Currying)". That would make it easy for people to recognise sections according to specific names they have heard of, with regards to functional programming. One often hears about the formal names for features of the language.

In general, I think that titles should contain a pedagogical title part, such as "multiple parameter lists" and a part containing some sort of reference to the more formal name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tfinneid , I am not sure how much value there is in adding the formal name to the title as well. Although I do not see a downside to it either (other than rather long section names). I would like @jvican 's opinion on this before I make my edits.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see value in having the technical term in the title just for those that are already familiar with the term and want to see what the Scala tour says about it, or how Scala allows to encode currying in the language. 😄


Here is an example, defined in [Traversable](/overviews/collections/trait-traversable.html) trait from Scala collections:

```
def foldLeft[B](z: B)(op: (B, A) => B): B
```

`foldLeft` applies a binary operator `op` to an initial value `z` and all elements of this traversable, going left to right. Here is an example of its usage:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would mention here one of the primary reasons why currying is useful: to fix the parameter z and reuse it in the call site several times. For example, when we're using the same parameter z all the time, it's better to reuse the same function.

I'm trying to find a good example that illustrates this scenario, but cannot come up with a good one. Do you happen to have a good one in mind? 😄

Copy link

@Adowrath Adowrath Jan 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that being able to reuse the parameter is just one of the advantages here.
Another is the special syntax you can get, list.foldLeft(z) { (acc, value) => /* ... */ }.

A bigger advantage is, though, to circumvent the limitation that scalac doesn't use type information in one parameter for another parameter's inference.
With a def foldLeft[B](z: B, op: (B, A) => B), you can't write List(1, 2).foldLeft(0, _ + _). It complains about the first _ having a missing parameter type.

Copy link
Member

@jvican jvican Jan 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bigger advantage is, though, that scalac doesn't use type information in one parameter for another parameter's inference.

Yup, that's quite technical but worth being mentioned.


```tut
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m: Int, n: Int) => m + n)
print(res) // 55
```

Starting with an initial value of 0, `foldLeft` applies the function `(m: Int, n: Int) => m + n` to each element in the List and the previous accumulated value.

Multiple parameter lists have a more verbose invocation syntax; and hence should be used sparingly. Suggested use cases include:

1. ##### Implicit parameters
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this rendered correctly in markdown?

To specify certain parameters in a parameter list as `implicit`, multiple parameter lists should be used. An example of this is:

```
def execute(arg: Int)(implicit ec: ExecutionContext) = ???
```

2. ##### Single functional parameter
In case of a single functional parameter, like `op` in the case of `foldLeft` above, multiple parameter lists allow a concise syntax to pass an anonymous function to the method.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to elaborate more here and maybe add a good example, as I described in the previous comment.

2 changes: 1 addition & 1 deletion _tour/nested-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ discourse: true
partof: scala-tour

num: 9
next-page: currying
next-page: multiple-parameter-lists
previous-page: higher-order-functions

redirect_from: "/tutorials/tour/nested-functions.html"
Expand Down
2 changes: 1 addition & 1 deletion _tour/tour-of-scala.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Scala is a modern multi-paradigm programming language designed to express common
Scala is a pure object-oriented language in the sense that [every value is an object](unified-types.html). Types and behavior of objects are described by [classes](classes.html) and [traits](traits.html). Classes are extended by subclassing and a flexible [mixin-based composition](mixin-class-composition.html) mechanism as a clean replacement for multiple inheritance.

## Scala is functional ##
Scala is also a functional language in the sense that [every function is a value](unified-types.html). Scala provides a [lightweight syntax](basics.html#functions) for defining anonymous functions, it supports [higher-order functions](higher-order-functions.html), it allows functions to be [nested](nested-functions.html), and supports [currying](currying.html). Scala's [case classes](case-classes.html) and its built-in support for [pattern matching](pattern-matching.html) model algebraic types used in many functional programming languages. [Singleton objects](singleton-objects.html) provide a convenient way to group functions that aren't members of a class.
Scala is also a functional language in the sense that [every function is a value](unified-types.html). Scala provides a [lightweight syntax](basics.html#functions) for defining anonymous functions, it supports [higher-order functions](higher-order-functions.html), it allows functions to be [nested](nested-functions.html), and supports [currying](multiple-parameter-lists.html). Scala's [case classes](case-classes.html) and its built-in support for [pattern matching](pattern-matching.html) model algebraic types used in many functional programming languages. [Singleton objects](singleton-objects.html) provide a convenient way to group functions that aren't members of a class.

Furthermore, Scala's notion of pattern matching naturally extends to the [processing of XML data](https://github.com/scala/scala-xml/wiki/XML-Processing) with the help of [right-ignoring sequence patterns](regular-expression-patterns.html), by way of general extension via [extractor objects](extractor-objects.html). In this context, [for comprehensions](for-comprehensions.html) are useful for formulating queries. These features make Scala ideal for developing applications like web services.

Expand Down