
Typelevel quicksort in Scala - lelf
http://jto.github.io/articles/typelevel_quicksort/
======
ajkjk
[warning: ignorant musing of someone who doesn't know Scala below]

This makes me wonder if 'values' can be though of as just subtypes of their
types. '5' extends 'Number', say. Is this how it's interpreted in the fully-
functional paradigm?

If you have

def fn(x: Int) : Int

then 'Int' is the type of all Ints, and you have to provide a specific int -
which is a subtype of Int, but you could imagine there being a subtype between
'Int' and '5', like:

5 <: intermediateType <: Int

So in order to 'invoke' a function you have to provide a subtype that reduces
it to one value, at the level of 5, not just any subtype of int. Meaning that
something about '5' makes it a special kind of subtype that can actually be
used to execute the function. Maybe that's what we mean by 'value'. I don't
know.

I do find the idea that fn(5) is a subtype of fn(x: Int) to be cute.

And that

def foo(x: Int): Int = fn(x)

has the 'subtype'

foo(5): fn(5)

seems suggestive.

~~~
tel
There's some significant sense to what you're talking about, so I'll share
some pointers into deeper waters.

The idea of a value being a type is the nature of "dependently typed"
languages. However, they do it the other way around: types are merely values.
This is very similar to what you're saying except DT languages would not have
that

    
    
        5 : 5
    

Instead, we introduce the idea of a singleton type. It works like this: for
any type A and any value (x : A), we have a type (Sing A x) with exactly one
value, (TheSing x : Sing A x).

The other thing to keep in mind is that subtyping is kind of a rocky place to
lay your type semantics. This is rough because most people are used to
subtyping in their types. Instead, we note that whenever we have that (A :> B)
then we have a function (A -> B) which is injective (really, an
"epimorphism"). This broaden's our view to consider any injective function
between types instead of merely some subtyping relation. Immediately it ought
to be clear that (a) this is intractable automatically and (b) it's far more
rich. Then it turns out that subtyping itself is fairly intractable (which
subtypes are the right ones? there are _many_ types intermediate between (Sing
Integer 5) and (Integer)).

So throw away automatic subsumption and require explicit coercions. This is
workable and indeed in use today.

~~~
seanmcdirmid
It seems that you can either fight subtyping (by avoiding it) or embrace it;
e.g. with pure subtype system:

[http://people.tamu.edu/~hiraditya/index_files/ProgLang_Prese...](http://people.tamu.edu/~hiraditya/index_files/ProgLang_Presentation.pdf)

You do exchange a typing judgment for a subtyping one.

I feel like we haven't really looked at subtyping enough. It might not be so
hard as it is different, that our existing type systems simply aren't suited
to it but we could come up with subtype systems that are.

------
steven2012
What sort of support does Scala have going forward? My understanding is that
although there are a lot of scala users, a lot of major corporate users have
backed away from it, ex. LinkedIn, Twitter, etc, because of fundamental issues
with the language.

~~~
lmm
As someone who's recently been jobhunting, Scala feels more popular than ever.
It may no longer be as hyped as it was (which is probably better for
everyone), but it's still growing.

And really there is no alternative - once you've used higher-kinded types
there's no going back. Some organizations make the switch to Haskell, but
that's not an option in many environments. Other than that, if you want
higher-kinded types there's nothing that's remotely as mature as Scala out
there.

I can't speak to "fundamental issues with the language" because I haven't
found any.

~~~
tormeh
The problem with Scala is that architects can and sometimes will get giddy and
create monsters. Scala is not like C++ where some features are dangerous, but
Scala has features that should be used with caution. The amount of times where
defining a partially applied higher-order function is the best way to solve a
problem is nonzero, but still really really low. So you let a team of giddy
developers eager to learn and apply new concepts loose and soon you have a
monster of a code base.

~~~
PhineasRex
Scala is like C++ where some features are dangerous. We've had significant
problems with parts of the standard library and had to resort to banning them
and writing our own alternatives.

~~~
allengeorge
Which portions of the standard library?

~~~
tormeh
Trying to perform a sequential operation on a parallel collection will not go
well, but other than that I haven't seen anything.

------
brudgers
This is cool and clever. But if it doesn't sort in O(1) memory, it's not
quicksort. With the lambda calculus lacking a concept of place, it's always
going to be tough ensure sorting in place...or randomized pivots as in Hoare's
algorithm.

~~~
sjolsen
Quicksort is O(log n) space, not O(1).

~~~
nightcracker
And if you're implementing pure Quicksort you have to make sure to recurse on
the smaller partition first, otherwise you're using O(n) space in the worst
case.

You don't have to do this if you're already using a hybrid sort to prevent
Quicksort's worst case, like introsort or (shameless self promotion) pdqsort
([https://github.com/orlp/pdqsort](https://github.com/orlp/pdqsort)).

~~~
sjolsen
>you have to make sure to recurse on the smaller partition first, otherwise
you're using O(n) space in the worst case

I haven't run the math, but I don't believe introsort fixes this. It's a
constant-factor optimization.

~~~
nightcracker
Introsort switches to heapsort if the recursion depth becomes too big to limit
runtime to O(n log n), which indirectly also limits space to O(log n).

