[r-t] Writing method display software

Alan Burlison alan.burlison at gmail.com
Sun Nov 29 06:17:06 UTC 2015

On 28/11/2015 21:11, Alexander Holroyd wrote:

> I'm interested to learn what programming languages people are using for
> ringing software, and (more imporantly) why.  I do not have any
> experience with Scala.  I have been mostly using Python recently, and,
> in comparison, every other language I see now looks hopelessly fussy and
> arcane to me. I find the python syntax extremely helpful, perhaps
> because it is very close to standard mathematical notation, which tends
> to be optimized for human readabaility.
> E.g. in python, testing for a jump change (as described below) would be
> def isjump(p):
>    return any(abs(i-x)>1 for (i,x) in enumerate(p))
> and composing two changes is
> def mul(p,q):
>    return [p[x] for x in q]
> Does one of you (Alan, Mark,...) want to explain to me why (e.g.) Scala
> might be better for some purposes?  I'm not being awkward (for once?) -
> I just want to learn...

Firstly, they are both fine languages, and I use both so I'm not going 
to criticise one at the expense of the other - language wars are so 
boring :-)

It's interesting to see your snippets above, the Scala equivalents from 
the stuff I've been playing with are:

def jumpChanges =
  deltas.zipWithIndex.filter(p => math.abs(p._1 - p._2) > 1).map(_._2)

def *(change: Change) =
  new Row(change.deltas.zipWithIndex.map(di => places(di._2 + di._1)))

They are very close - jumpChanges returns the list of jump changes so 
it's slightly more complicated than yours and the multiplication is a 
little different because I represent changes as position deltas, i.e. 
[0,1,-1,0] because it makes life simpler elsewhere, but stylistically 
they are similar. There's a good reason for that, it's because both 
snippets are written in a Functional style. You can do Functional 
Programming (FP) in Python but it's not its primary design goal and it 
lacks some key features such as immutability, pattern matching, 
currying, function composition and so forth, all of which Scala (and 
other FP languages) have.

Rather than arguing about how A is better than B I think it's more 
useful to look at some of the characteristics of each so you can decide 
which is the right choice for each circumstance. And I'd like to add the 
C++ Ringing Class Library (RCL) into the mix because that's a 
sophisticated library that has it's own advantages that need to be 
considered as well.

* Python is loosely typed, Scala & C++ are strongly typed. That means 
lots of errors in Python are only detected at run-time, Scala & C++ will 
detect them at compile-time. Scala in particular has an incredibly 
sophisticated type system that can be used to do Wondrous Things, but it 
is not easy to use well.

* Python is interpreted, Scala and C++ are compiled, with Scala being 
compiled to JVM bytecode and C++ to platform-specific machine code. That 
means Python has a performance disadvantage compared to Scala & the RCL. 
Scala and RCL will be closer in performance, but the RCL will probably 
win in most circumstances.

* Python is relatively easy to learn, Scala and C++/RCL have bigger 
learning curves.

* Python & C++/RCL favour mutable data, Scala favours immutable data. 
Immutability means that once an object is assigned, its values may not 
be modified. Immutable data can be shared freely between threads without 
having to lock it - that's important if you are trying to scale across 
many cores. You can do the same thing in Python & C++ but it's harder as 
you have to do it by convention, which means mistakes are easy.

* Python will not scale across many cores. That's because even though 
Python has threads, it has the GIL (Global Interpreter Lock) which 
limits the amount of parallelism you can achieve. Neither Scala nor C++ 
have that issue. Threading in Scala is relatively easy, for example many 
of the standard collection classes have parallel variants which will 
automagically multi-thread operations on them. With C++ it's all down to 
you to get it right, and that's hard.

* Python and Scala are fairly platform-independent, C++ is less so, 
although in the case of the RCL that shouldn't be too much of a problem 
as it is platform-independent in nature anyway.

* Python and Scala both look after memory management for you, C++ 
doesn't (although libraries can help). Unless you are diligent it's easy 
to get memory leaks and heap corruptions in C++.

* C++ has the RCL which is a mature and, as far as I can tell, fairly 
widely used library within the method composition fraternity. As far as 
I know, neither Python nor Scala have an equivalent, so you'll be mostly 
on your own with those languages.

The above are broad-brush statements and can obviously be nit-picked if 
people are so minded. What I've tried to give is a broad flavour of the 
differences between the three rather than a full comparison. All of them 
are the right choice for particular circumstances, the trick is deciding 
which. For example, manipulating existing compositions could be done 
just fine in Python but if you wanted to do exhaustive searching of 
composition spaces then either Scala or the RCL would be better. RCL 
probably wins in performance terms on PC-class machines and is a rich 
library, Scala may win when using machines with hundreds of cores 
because it is easier to handle parallelism, but you'd have to write your 
own support code as there's no RCL equivalent. Scala may also win if you 
want to do more mathematical-style manipulation, as FP languages lend 
themselves to that quite nicely.

I picked Scala because I wanted to fiddle with code to learn how 
computer-assisted method composition works, and because I have access to 
some fairly large machines. I'm arguably an outlier, so Scala may well 
not be the right choice for other people.

And remember, Real Programmers can write FORTRAN programs in any 
language. Some things never change ;-)

Alan Burlison

More information about the ringing-theory mailing list