Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 627783
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T19:33:56+00:00 2026-05-13T19:33:56+00:00

I am trying to understand the Scala quicksort example from Wikipedia. How could the

  • 0

I am trying to understand the Scala quicksort example from Wikipedia. How could the sample be disassembled step by step and what does all the syntactic sugar involved mean?

def qsort: List[Int] => List[Int] = {
  case Nil => Nil
  case pivot :: tail =>
    val (smaller, rest) = tail.partition(_ < pivot)
    qsort(smaller) ::: pivot :: qsort(rest)
}

As much as I can gather at this stage qsort is a function that takes no parameters and returns a new Function1[List[Int],List[Int]] that implements quicksort through usage of pattern matching, list manipulation and recursive calls. But I can’t quite figure out where the pivot comes from, and how exactly the pattern matching syntax works in this case.

UPDATE:

Thanks everyone for the great explanations!

I just wanted to share another example of quicksort implementation which I have discovered in the Scala by Example by Martin Odersky. Although based around arrays instead of lists and less of a show-off in terms of varios Scala features I personally find it much less convoluted than its Wikipedia counterpart, and just so much more clear and to the point expression of the underlying algorithm:

def sort(xs: Array[Int]): Array[Int] = {
    if (xs.length <= 1) xs
    else {
        val pivot = xs(xs.length / 2)
        Array.concat(
            sort(xs filter (pivot >)),
            xs filter (pivot ==),
            sort(xs filter (pivot <)))
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T19:33:56+00:00Added an answer on May 13, 2026 at 7:33 pm
    def qsort: List[Int] => List[Int] = { 
      case Nil => Nil 
      case pivot :: tail => 
        val (smaller, rest) = tail.partition(_ < pivot) 
        qsort(smaller) ::: pivot :: qsort(rest) 
    }
    

    Let’s rewrite that. First, replace the function literal with an instance of Function1:

    def qsort: List[Int] => List[Int] = new Function1[List[Int], List[Int]] {
      def apply(input: List[Int]): List[Int] = input match {
        case Nil => Nil 
        case pivot :: tail => 
          val (smaller, rest) = tail.partition(_ < pivot) 
          qsort(smaller) ::: pivot :: qsort(rest) 
      }
    }
    

    Next, I’m going to replace the pattern match with equivalent if/else statements. Note that they are equivalent, not the same. The bytecode for pattern matches are more optimized. For instance, the second if and the exception throwing below do not exist, because the compile knows the second match will always happen if the first fails.

    def qsort: List[Int] => List[Int] = new Function1[List[Int], List[Int]] {
      def apply(input: List[Int]): List[Int] = if (input == Nil) {
        Nil
      } else if (input.isInstanceOf[::[_]] && 
                 scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]) != None) {
        val unapplyResult = scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]).get
        val pivot = unapplyResult._1
        val tail = unapplyResult._2
        val (smaller, rest) = tail.partition(_ < pivot) 
        qsort(smaller) ::: pivot :: qsort(rest) 
      } else {
        throw new scala.MatchError(input)
      }
    }
    

    Actually, val (smaller, rest) is pattern match as well, so Let’s decompose it as well:

    def qsort: List[Int] => List[Int] = new Function1[List[Int], List[Int]] {
      def apply(input: List[Int]): List[Int] = if (input == Nil) {
        Nil
      } else if (input.isInstanceOf[::[_]] && 
                 scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]) != None) {
        val unapplyResult0 = scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]).get
        val pivot = unapplyResult0._1
        val tail = unapplyResult0._2
        val tmp0 = tail.partition(_ < pivot)
        if (Tuple2.unapply(tmp0) == None)
          throw new scala.MatchError(tmp0)
        val unapplyResult1 = Tuple2.unapply(tmp0).get
        val smaller = unapplyResult1._1
        val rest = unapplyResult1._2
        qsort(smaller) ::: pivot :: qsort(rest) 
      } else {
        throw new scala.MatchError(input)
      }
    }
    

    Obviously, this is highly unoptmized. Even worse, there are some function calls being done more than once, which doesn’t happen in the original. Unfortunately, to fix that would require some structural changes to the code.

    There’s still some syntactic sugar here. There is an anonymous function being passed to partition, and there is the syntactic sugar for calling functions. Rewriting those yields the following:

    def qsort: List[Int] => List[Int] = new Function1[List[Int], List[Int]] {
      def apply(input: List[Int]): List[Int] = if (input == Nil) {
        Nil
      } else if (input.isInstanceOf[::[_]] &&
                 scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]) != None) {
        val unapplyResult0 = scala.collection.immutable.::.unapply(input.asInstanceOf[::[Int]]).get
        val pivot = unapplyResult0._1
        val tail = unapplyResult0._2
        val func0 = new Function1[Int, Boolean] {
          def apply(input: Int): Boolean = input < pivot
        }
        val tmp0 = tail.partition(func0)
        if (Tuple2.unapply(tmp0) == None)
          throw new scala.MatchError(tmp0)
        val unapplyResult1 = Tuple2.unapply(tmp0).get
        val smaller = unapplyResult1._1
        val rest = unapplyResult1._2
        qsort.apply(smaller) ::: pivot :: qsort.apply(rest) 
      } else {
        throw new scala.MatchError(input)
      }
    }
    

    For once, the extensive explanations about each syntactic sugar and how it works are being done by others. 🙂 I hope this complements their answers. Just as a final note, the following two lines are equivalent:

        qsort(smaller) ::: pivot :: qsort(rest) 
        qsort(rest).::(pivot).:::(qsort(smaller))
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to understand type members in Scala. I wrote a simple example
I'm trying to understand what Scala does with Case Classes that makes them somehow
I am fairly new to Scala. I am trying to understand how/if scala does
I'm trying to understand the behavior of Scala for-loop implicit box/unboxing of numerical types.
I'm trying to understand the advantages of currying over partial applications in Scala. Please
I'm trying to understand the implementation of List s in Scala. In particular I'm
I've got part of code from friend and I'm trying to understand it and
I'm trying to understand a particular Perl code from vcake . Usually I find
I am fairly new to Scala and am trying to understand the collections hierarchy.
Here's the code I'm trying to understand (it's from http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/ ): object io {

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.