Culture / Development / Technology

Solving One Problem with 16 Programming Languages, on YouTube

26 Sep 2021 6:00am, by
icons of various programming languages

A video blogger recently tackled the same programming problem using 16 different languages, giving viewers a chance to see a wide variety of results, share their own suggestions, and learn about programming languages along the way.

It was a fun demonstration of just how many choices there are in the complex world of programming languages today. But for at least one of the languages, it also turned into a demonstration of the power of a community.

The big event happened on code_report, a YouTube channel “dedicated to competitive programming”. It’s the work of Conor Hoekstra, a senior library software engineer at NVIDIA (working on its RAPIDS suite for data science and analytics pipelines) who’s also held roles at Amazon and Moody’s Analytics. Hoekstra also co-hosts a podcast about array-oriented programming languages and another one about programming-related topics like algorithms and data structures.

But for this YouTube channel, he reviews the solutions from coding contests like LeetCode, HackerRank, Topcoder and Codeforces — and also creates videos about related programming topics like data structures, algorithms and complexity (which were likely to prove useful in those competitions).

Fortran Has Fans

To explore 16 programming languages, Hoekstra chose a relatively simple problem from a LeetCode coding competition: Given a list of numbers, identify the smallest and largest number — and then find the largest number that can be divided into both of them (without a remainder).

The languages chosen for the solution:

  • C++
  • Rust
  • D
  • Clojure
  • Ruby
  • Elixir
  • Raku [Perl 6]
  • Haskell
  • Racket
  • Julia
  • Python
  • APL
  • J
  • BQN
  • Pharo Smalltalk
  • Fortran

(The video explained that the last two languages were last-minute additions chosen by Hoekstra’s audience online. “I tweeted this out and asked my followers,” Hoekstra said, and Fortran received “a whopping 27 ‘hearts’ on a single tweet!”)

Drastic Differences

Hoekstra called it “a pretty straightforward problem, but you’ll soon see, especially when we get to the array languages, that you can solve these in a drastically different way than compared to languages like Python or Ruby.”

The little differences quickly became apparent. Python already has built-in functions for all the necessary operations — for finding the smallest number, the largest number, and then the “greatest common divisor” that they share.

Python GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

But things really started looking different when Hoekstra got to the functional language Haskell. Its liftM2 function basically maps the values from minimum and maximum into the input for the gcd function — all in a single line.

And best of all, since Haskell used so-called Tacit or point-free style programming, which doesn’t specify arguments in its function definitions, the Haskell solution didn’t even need to mention the array of numbers…

Haskell GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

The low-level D programming language requires that the functions be imported — but at least that language uses universal functional call syntax, which lets functions be called using the familiar “method” style of object-oriented programming. Said the host, “This is really, really nice, in my opinion.”

D programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

With Rust, Hoekstra complained that, like C++, there’s “a lot of ceremony here” — in this case because the min and max functions require both the iter() method to actually iterate through each value in the list of numbers, and also the unwrap() method to extract just the value from Rust’s more complex enumerated Result type (which includes error handling information).

And, Hoekstra, noted: “there’s also a lot of noise in the num::integer:: namespace in order to get access to the gcd function. But other than that, it’s still a very nice solution.”

Rust programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

But there were even more significant differences, mostly because Hoekstra is a fan of array programming languages. With APL, the gist of the solution (to the right of the pink arrow) is just five characters. (The first two characters find the maximum value, the last two characters find the minimum value, and the green v in the middle finds their greatest common divisor.)

APL programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

There’s a similar structure in the J programming language — also an array programming language — but “J is an evolved version of APL, and used ASCII diagraphs and not Unicode symbols,” Hoekstra noted. So the maximum-finding function is represented with >. while the minimum-finding function is <.

J programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

The solutions got more and more exotic. The BQN language is still an array-driven language in the APL family (according to the APL Wiki) — but BQN uses its own unique set of characters. Because there’s no pre-built function for finding the greatest common divisor, that function has to be defined in its own separate line of code.

Hoekstra admitted that he just copied the code from an online source. (“I don’t actually understand it, because I’m a BQN novice.”) But once it’s defined in the first line, it can be called as part of the solution in the second line.

BQN programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

Vying with Viewers

Judging by audience reactions, it looks like the internet enjoyed riding along and sharing the experience.

The video ultimately attracted 135 comments, where Hoekstra’s viewers shared their own opinions on programming languages (“The Haskell solution was beautifully elegant, APL was a bit too cryptic for me.”)  as well as other comments on the proceedings. (“People that requested Fortran wanted to see you suffer.”)

“I have received close to a hundred comments at this point, and a lot of them were improvements on the solutions that I showed in that video,” Hoekstra announced in a second video.

Julia’s solution had looked similar to Python’s — albeit with Julia’s “splat” operator (indicated by the three-dot ellipsis) to signify that more than one value will be tested.

Julia GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

But viewers had suggested a simpler syntax. Julia also has two built-in minimum- and maximum-finding functions which don’t require the ellipsis. There’s also a single function that returns both values — named extrema. And then the solution got even simpler when Hoekstra uses Julia’s composition operator to produce a point-free solution (with the collect function transforming the two values into a list format so it can be fed into gcd).

 Julia (better fourth) GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

“In my opinion, this is the most beautiful solution of all,” Hoekstra added — partly because it demonstrates the elegance of point-free solutions.

Viewers had also suggested some elegant improvements for the solution Hoekstra wrote in Raku (the language formerly known as Perl 6). In Raku, gcd is an “infix” function that can be placed between two values just like mathematical operators (like a plus or minus sig). And then the two values that it’s operating on can be the results of object-style methods being called on the array of numbers. (Because, as Perl creator Larry Wall once said, in Raku “Everything is an object. But only if you want it to be.”)

Raku GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

Ironically, the Pharo Smalltalk solution also ended up resembling the Raku solution (with its own gcd: function also appearing as an “infix” operator between the two minimum- and maximum-returning functions).

Pharo Smalltalk programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

But Hoekstra’s viewers had pointed out that Raku also has a dedicated minmax function that can return both values at once — resulting in another single-line solution where that result becomes the input for Raku’s gcd function.

Raku GCD second solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

“I do prefer this,” Hoekstra said. “Any time you can use an algorithm that’s going to do a single pass instead of two passes … I think that’s much preferable.”

Fun with Fortran

In the first video, Hoekstra ranked Fortran’s solution as the worst, calling it one of those languages cluttered with “ceremony.” But his solution came with a disclaimer. “Note that this is the first Fortran piece of code that I’ve written in my life, so odds are there’s probably better ways to do this … After 40 minutes of just getting this code up and running, I called it a day.”

Fortran programming language GCD solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

Fortran (separate GCD function code) solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

But in the follow-up video, Hoekstra acknowledged that “The response that I got from the Fortran community was so amazing.”

The respondents included Jacob Williams, a Fortran programmer and orbital mechanic at the NASA Johnson Space Center.

And Hoekstra’s video also drew a response from Milan Curcic, a long-time Fortran programmer and author of the book “Modern Fortran.” On Twitter, Curic thanked Hoekstra for including Fortran and suggested an alternate implementation (which includes a greatest-common-denominator function that was proposed for the language in March).

Fortran (second GCD function code) solution for LeetCode problem by Code_Report on YouTube (screenshot from video)

Hoekstra learned that the temporary res variable wasn’t necessary, since the result could just be returned without separately assigning it. And some new syntactic sugar in Fortran now allows the length of a list to be indicated with just a colon — rather than Hoekstra’s unwieldy variable numsSize — which eliminates the need for an entire line of code assigning it to a dedicated variable.

“We went from what we had before to just basically two lines in the body of our function,” Hoekstra said.  “So this, I thought, was absolutely awesome!”

He is thrilled that a new comment on its issue ticket in GitHub now even specifically mentions his video.

“The Fortran language Twitter account even retweeted my initial video tweet saying they’re going to work on improving their tutorials in the future, but just thanks for covering it — which I thought was awesome,” he added.

Hoekstra called the response “a model of how a community should act if they’re trying to get people to be more excited about their language.”

He concluded, “I hope you learned something from this video, as I definitely did from the comments.”


WebReduce

A newsletter digest of the week’s most important stories & analyses.