
Haskell vs. Ada vs. C++ vs. Awk vs (1994) [pdf] - tosh
http://haskell.cs.yale.edu/wp-content/uploads/2011/03/HaskellVsAda-NSWC.pdf
======
mpweiher
This is a long time ago, but I remember coming across this competition when
studying software architecture for my Diplomarbeit.

IIRC, the Haskell solutions were disqualified, and actually for good reasons.
The competition was about architecture of the system, with the geo _server_ an
example component. Notice that for example Rapide is an Architecture
Description Language (ADL).

As far as I can tell, the Haskell team(s) only concerned themselves with the
(purposely) simplistic/simplified functionality of the geoserver component,
and not the architectural concerns that were the actual point of the
competition.

Which, quite frankly, is something I see frequently from the FP community:
declare that <complicated actual problem> is _really_ <much simpler problem
easily solved by FP>, solve the simpler problem that ignores almost all the
real requirements, declare victory and go home.

~~~
eklavya
I find that statement hard to believe when so much complicated software in the
industry is built using Scala/Haskell/OCaml not to mention so much of
research. (STM is an example of how some complicated stuff is solved easily
using FP).

Why do you feel they avoid real problems? When did you see that?

~~~
oconnore
One time someone posted a "concurrency challenge", and I spent a couple
minutes typing out the STM calls that solved it. They balked, for some
combination of: that doesn't work in C++, you're not really following the
spirit of the challenge, etc. Later they posted a 100+ line solution using
condition variables.

Lesson: the "real requirements" typically include that the solution doesn't
require learning anything new or weird.

~~~
mpweiher
Yes, that is true, and I sympathize, I am also often in the position of having
a solution that is simpler than seems possible to the "less enlightened".

However, "real requirements" often do include relevant things that aren't
stated. I don't know if this was the case here, but "concurrency" is often
something you need because of "performance", and so a Haskell STM solution
_may_ not be what your C++ hacker is looking for.

The prime example of this is the Haskell "Quicksort" implementation, which is,
of course, not actually quick and only vaguely related to the idea of
Quicksort.

Another example was SPJ's talk about parallel programming in Haskell, where
the result was that a 6 core Haskell version was equivalent to a single core C
solution. In the same talk he also boasted that "this is only possible with
Haskell", to which an audience member replied that the HPC community had been
doing this for well over a decade with FORTRAN.

The problem with the FP community is that there is so much of the latter
examples going on that the true cases of the former tend to be less
believable.

~~~
copx
> _Another example was SPJ 's talk about parallel programming in Haskell,
> where the result was that a 6 core Haskell version was equivalent to a
> single core C solution._

Reminds me of a Rich Hickey talk were he proudly declared that a Clojure
solution based on its persistent vector type running on four cores was as fast
as the Java/mutable vector solution running on one!

The point there was supposed to be that Clojure's inefficiency is more than
counterbalanced by the fact that it makes writing parallel code easier.

I was not convinced, though.

> _In the same talk he also boasted that "this is only possible with Haskell",
> to which an audience member replied that the HPC community had been doing
> this for well over a decade with FORTRAN._

The FP advocates always seem to use examples which show non-interactive
processing of "embarrassingly parallel" vector data. And yes, that is trivial
in any language. Even in C land all you need to do is to add one keyword /
annotation to your for-loop and you are good.

~~~
nickpsecurity
Case in point:

[https://en.wikipedia.org/wiki/Cilk](https://en.wikipedia.org/wiki/Cilk)

------
saosebastiao
It's old. It's so old, it predates Haskell's monads as an idea, let alone a
solution to the IO problem. It was before Higher Kinded Types and GADTs.
Linked Lists were still the primary data structure for everything. Haskell was
more like Miranda than it was like Haskell today.

Not only that, but it excluded some of the more prominent languages for
prototyping of the time: Smalltalk, SML, Eiffel, and Objective C.

And if you were to do it today, you'd invariably have to include languages
that have had 20 years to catch up. Would the same result hold in a world with
Scala, Ocaml, F#, Idris, Agda, Swift, and Rust?

Let's face it, this study was a victory for higher order functions and ADTs
with pattern matching. Let's not pretend it was anything more than that.

~~~
wyager
> this study was a victory for higher order functions and ADTs with pattern
> matching.

So, the bread and butter of Haskell?

There are few languages that do these two things nearly as well as Haskell.
All of them are ML derivatives. Haskell, OCaml, and F# come to mind.

Rust has almost-as-good ADTs, but no higher order functions. A number popular
of languages support both of these concepts, but not nearly as natively or
conveniently.

~~~
leshow
Rust has first class functions and thus has higher order functions. Iterators
have a bunch of higher order functions, map for example:

let a = (0..10).map(|x| x*x).collect::<Vec<_>>();

~~~
wyager
I've already responded a couple times with the same content, but the short of
it is that rust HOFs are very limited due to its memory model. True
functional-style HOFs require arbitrarily sized closures on the heap, and the
only way to get that in Rust is by boxing the closures, which ends up being
relatively inconvenient. There's a reason no one uses HOFs in rust outside of
trivially inlinable examples like the one you give. There are no composition
or application operators in the standard library because it's just too
syntactically inconvenient to work with HOFs in the same way you would in a
functional language.

~~~
leshow
It's true it's not nearly as ergonomic as haskell to pass around functions.
You don't necessarily need to box the closure up on the heap in order to store
a bunch of functions in say a vector though, it just needs to sit behind some
kind of &, &mut, Arc, Rc, Box, etc.

I have seen a few hashmaps that store functions as values, in terms of real
world uses.

You mentioned storing functions (closures here) in a vector, this isn't too
much of a stretch I don't think:

    
    
        let x = |c| c * 2;
        let y = |v| v + 2;
    
        let b: Vec<&Fn(_) -> _> = vec![&x, &y];
    

Definitely not "no higher order functions" as you claimed.

~~~
wyager
By the same token, C "supports" higher order functions; you can pass around a
function pointer and a pointer to a closure. It's sort of an idiomatic
question; HOFs are inconvenient enough in Rust that no one really uses them
outside of a few specific cases (like local maps and folds).

~~~
leshow
There's a wide berth between inconvenient, which is subjective, and not
supported. HOF's exist in Rust, could the ergonomics be better; that's up for
debate.

------
rekado
Speaking of Haskell, Yale, and the 1990s: I ported the 1993 release of Yale
Haskell to run on top of GNU CLISP. It only required a couple of small
changes. The code is here: [http://git.elephly.net/software/yale-
haskell.git](http://git.elephly.net/software/yale-haskell.git)

------
58028641
After learning Haskell, I found its approach to solving problems much simpler.
I will admit that it was very unusual at first. Lens, monads, template
Haskell, and a very powerful types system are the key features that make it
standout.

~~~
acchow
IMO, if you just use C++ without subtyping (no inheritance) and only immutable
structures, you get most of the "simplicity" of Haskell.

And with C++17 variant, you also almost get pattern matching.

(also, as per "powerful type system", you can do dependent types in C++)

~~~
lmm
Simplicity can never happen without enforcement. If there is no way to
_automatically_ enforce the use of this simple subset of C++ then it's
impossible to use it on a real project where you have more than 1 developer. A
lot of people seem to think it's a trivial, handwavable exercise to come up
with this subset - but no-one has ever managed to actually do it.
[http://robert.ocallahan.org/2016/06/safe-c-subset-is-
vapourw...](http://robert.ocallahan.org/2016/06/safe-c-subset-is-
vapourware.html)

~~~
AnimalMuppet
Is that a plus or a minus? If you're not a purity zealot, then you can step
out of those rules where it makes sense, and regard the ability to do so as a
plus. If you _are_ a purity zealot, you're appalled at the thought, and want
to _force_ people not to do that.

~~~
lmm
I'm not a purity zealot, I'm a correctness zealot. Working on real projects
means working with people who are less competent than they think they are; I
want to _force_ those people to not introduce bugs, and I'm broadly
indifferent to the mechanism for doing that.

------
crystalPalace
I really want to see the AWK geo-server implementation. I also want to know
who the expert AWK programmer was. AWK is cool, don't get me wrong, but I
don't typically think of it as a general purpose programming language.

~~~
moftz
It seemed like one of "I did it because I could" kind of projects. I've used
awk to setup some complicated reformatting of text files that I needed cron
but I've never even considered using it as a prototyping language. I wonder
what kind of ADTs you can build using it and how viable it would be as the
backend of a simpler scripting language.

------
qwertyuiop924
This was 1994. Why did they pick AWK as an example language? Perl was already
fairly mature at that point.

I happen to love AWK, but this is absolutely the wrong usecase for it: AWK is
a highly domain-specific language, and using it here just makes scripting
languages look worse than they are (and in the early 90s, scripting languages
weren't that great).

------
0x54MUR41
Previous submission on HN:
[https://news.ycombinator.com/item?id=13251855](https://news.ycombinator.com/item?id=13251855)
a few days ago.

------
tibbetts
Disappointed that PDF wasn't one of the programming languages.

~~~
cosinetau
It would be great if that format were somehow Turing complete.

~~~
nradov
Well you can run JavaScript inside a PDF, so technically it is Turing
complete.

~~~
hardwaresofton
From ~30s of searching, it looks like that's an Adobe Reader feature:
[https://stackoverflow.com/questions/9219807/using-
javascript...](https://stackoverflow.com/questions/9219807/using-javascript-
inside-a-pdf)

My original comment was going to be "Who thought that was a good idea? Maybe
there are reasons, but that sounds like a terrible idea at face value".

~~~
kccqzy
Chrome's builtin PDF reader supports it. You can even find a PDF that uses JS
to play a game of pong in Chrome.

~~~
therein
Well, out of all the places that makes sense, it's Chrome after all.

Either way, it sounds like a pretty bad idea to add this as a feature to Adobe
Reader or somehow to the PDF spec. Especially since PDF remote code execution
exploits happen relatively often.

------
otabdeveloper
> 1994

Probably not relevant anymore.

~~~
jonathonf
"Those who forget the lessons of the past..."

