[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 ;-)
http://web.mit.edu/humor/Computers/real.programmers
--
Alan Burlison
--
More information about the ringing-theory
mailing list