Skip to content

Potential Semantic Clarity #2347

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 1 commit into from
Closed

Potential Semantic Clarity #2347

wants to merge 1 commit into from

Conversation

0xrutvij
Copy link

Hello! Firstly, I would like to thank all the contributors for the awesome tour of Scala Lang. While going through the example, the usage of Node[Bird] type for birdList threw me in a loop for a moment. The location of usage has been proposed as a change for both demonstration purposes and as a potential change.

I understand traits can be used to describe a type, but in this instance wouldn't it be clearer to say ListNode[Bird] instead? Seeing that the value name –birdList– indicates we are going for a list. From what I can surmise, the Node trait can be implemented by say, a GraphNode which uses the prepend method in some way (one might argue it to be a convoluted use case). For the sake of clarity and consistency with the semantic meaning of the example, I believe ListNode[Bird] would be a better choice.

Hello! Firstly, I would like to thank all the contributors for the awesome tour of Scala Lang. While going through the example, the usage of `Node[Bird]` type for birdList threw me in a loop for a moment. The location of usage has been proposed as a change for both demonstration purposes and as a potential change.

I understand traits can be used to describe a type, but in this instance wouldn't it be clearer to say `ListNode[Bird]` instead? Seeing that the value name –birdList– indicates we are going for a list. From what I can surmise, the Node trait can be implemented by say, a GraphNode which uses the prepend method in some way (one might argue it to be a convoluted use case). For the sake of clarity and consistency with the semantic meaning of the example, I believe `ListNode[Bird]` would be a better choice.
@som-snytt
Copy link
Contributor

The section is demonstrating why you need a type parameter for the method and give it a bound.

It doesn't quite demonstrate that.

This shows that you can prepend a "disparate" swallow:

  val africanSwallowList: Node[AfricanSwallow] = ListNode[AfricanSwallow](AfricanSwallow(), Nil())
  val birdList: Node[Bird] = africanSwallowList
  val s0 = birdList.prepend(EuropeanSwallow())
  val s1 = africanSwallowList.prepend(EuropeanSwallow())

(This is that thing where s0 is still Node[Bird] but s1 is Node[Product with Bird with Serializable].)

The last line of text is pointing out that the assignment to birdList works and s0 also works. But I think it is more surprising that s1 works.

Here is an example of why Node is useful, namely, you don't know you have a non-empty list until you prepend:

val swallowsFromAntarctica: Node[Bird] = Nil()

Normally you'd use pattern matching to inspect a Node. And now I see that ListNode is a case class but has extra members.

@som-snytt
Copy link
Contributor

Possibly superseded by #2355 which attempts to shake it out a bit.

@som-snytt
Copy link
Contributor

som-snytt commented Mar 31, 2022

Thanks!

Expanding this recommendation at #2355 to avoid Node and say List.

@som-snytt som-snytt closed this Mar 31, 2022
@0xrutvij 0xrutvij deleted the patch-1 branch May 26, 2022 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants