Skip to content
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

Improve list comprehensions quicksort example #8008

Merged
merged 1 commit into from
Jan 11, 2024

Conversation

Maria-12648430
Copy link
Contributor

Actually, I just wanted to add a missing word, but then went on to make the description a little more elaborate and hopefully clearer. The nested list structure may seem a little too much, but I think this way the explanation is more structured.

Copy link
Contributor

github-actions bot commented Jan 9, 2024

CT Test Results

  1 files   11 suites   5m 34s ⏱️
 93 tests  91 ✅ 2 💤 0 ❌
109 runs  107 ✅ 2 💤 0 ❌

Results for commit d9687b5.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

Copy link
Contributor

@bjorng bjorng left a comment

Choose a reason for hiding this comment

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

Looks good except for a typo.

While you are it, perhaps it would be a good idea to mention that while this way to sort makes a neat example, a more efficient way to sort in Erlang is lists:sort/1?

@bjorng bjorng self-assigned this Jan 10, 2024
@bjorng bjorng added team:VM Assigned to OTP team VM documentation labels Jan 10, 2024
@Maria-12648430
Copy link
Contributor Author

@bjorng on a different but related topic... In the example code, there is a list concatenation like Smaller++[Pivot]++Larger (simplified).

At first I thought that this is an inefficient way to do things (simple enough for an example, though), assuming that the first ++ would construct a list of all elements in Smaller with Pivot tacked on at the end, and that the second ++ would then work on this list to append Larger. This would involve a traversal Smaller to tack on Pivot, and another of the Smaller-with-Pivot-tacked-on list to append Larger. And if that was the case, doing it like Smaller++[Pivot|Larger] should be more efficient, saving one traversal.

However, timing the two approaches does not yield any difference. The timings vary wildly within each of the approaches, but on average they seem to amount to the roughly same. This makes me suspect that there is some compiler magic at work?

@RaimoNiskanen
Copy link
Contributor

However, timing the two approaches does not yield any difference.

IIRC the compiler optimizes an expession [A,B,...Z] ++ TailExpression into [A,B,...Z | TailExpression].
And since ++ is right associative HeadExpression ++ [A,B,...Z] ++ TailExpression gets the same optimization, of the second ++.

For strings there is even more special treatment:

0> "a" ++ x = [$a | x].
[97|x]

@bjorng
Copy link
Contributor

bjorng commented Jan 11, 2024

This makes me suspect that there is some compiler magic at work?

Yes, as @RaimoNiskanen said, the list [Pivot] is never actually built.

But far more important is that ++ is a right-associate operator, as Raimo also pointed out. Even without that minor optimization, concatenating three or more lists is still efficient.

That means that the expression A ++ B ++ C ++ D will be evaluated like so:

L0 = C ++ D,
L1 = B + L0,
A ++ L1

meaning that each of the lists C, B, and A will only be traversed once (in that order).

@Maria-12648430
Copy link
Contributor Author

Thanks for the explanation @bjorng and @RaimoNiskanen 🤗

@juhlig
Copy link
Contributor

juhlig commented Jan 11, 2024

@RaimoNiskanen

For strings there is even more special treatment:

0> "a" ++ x = [$a | x].
[97|x]

Hm, I don't see any special treatment for specifically strings here? I mean, [$a] ++ x (ie, without the string syntax) also works? Am I missing something?

@bjorng bjorng merged commit 4e359b1 into erlang:master Jan 11, 2024
15 checks passed
@bjorng
Copy link
Contributor

bjorng commented Jan 11, 2024

Thanks for your pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation team:VM Assigned to OTP team VM
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants