We chose it because logic/functional languages are great for tree processing, Mercury was designed for large projects, and because in 2002 there really weren't many other options around.
Its syntax and semantics are derived from Prolog, it borrows a lot from Haskell (types, type classes), in spirit it's reminiscent of OCaml (niche, little weird) and with support for unique modes there is some interesting overlap with Rust, although this aspect of the language still needs more compiler support.
All in all, definitely worth checking out.
Select offline, The book, 4.2 and it generates the book on the fly.
Full disclosure: If I'd had my way we would have used LaTeX templates to produce the PDFs but the previous developers had already implemented the HTML->PDF flow, so we just replaced the old, defunct service with Prince, which did a surprisingly good job, IMO.
It's not just that. Print to PDF for basic stuff it can be an option. For complex documents, print workflows, etc, it's a non-starter.
If you have to repeat this process 2000 times, it becomes time consuming. It doesn't scale for a single user needing 2000 pdfs to do the process manually.
It's a bit pricey, though (at leats, pricer than "free"). So we're using WeasyPrint on more recent projects.
WeasyPrint is open source and written in Python. It's much slower than Prince, though, but this can be mitigated by caching renderings. I'm would bet that it's as standard-compliant or bug-free than Prince, but it's good enough for us.
When / if our customers ask for more speed or pixel-perfect support (with the $$$ to match), we will definitively try Prince again.
HTML to PDF is something I never thought about since Firefox does it (and results usually aren’t great).
The browsers don't specialise in PDF generation, and we do :)
Unfortunately, the documentation, FAQ and User Guide all failed in succinctly giving me the information I need: what can it do well, what does a known snippet look like implemented in <Lang>, how does it compare to other languages, etc.
I appreciate the fact that the documentation seems extensive and well-structured, but that is only helpful to persons who already know they are going to use the language (i.e. University Students in Melbourne?).
Mercury started out as a subset of Prolog, and is still very Prolog-like. The Mercury compiler is written in Mercury, and that's how it was originally bootstrapped. So anyone that knows Prolog should feel reasonably comfortable writing code in Mercury.
One major difference is the type system, which feels more like Haskell than Prolog (where everything is an atom). Another is the way it handles predicates/functions that can generate multiple outputs - there are no cuts (!), and if a predicate can generate multiple values then it should be declared as such. These type and mode declarations allow the compiler to generate much more efficient code than a Prolog interpreter.
Everything in Prolog is a "term", that can be a predicate, a constant or a
variable. Constants are predicate symbols (called "functors"), numbers, or
character strings of the form [a-z][A-Za-z0-9_]& (where & is the Kleene star that I don't know how to enter in HN comments), or any string enclosed in
single quotes, ''. Variables are upper case letters. And predicates are atoms
followed by a vector of terms in parentheses, their arguments.
There is often confusion on the matter, because all constants are considered
"atomic" and people sometimes use the term "atom" to refer to all atomic
constants (where the distinction is clear from the context; allegedly).
However, numbers are not atoms, so the following is true:
Then there's the fact that, in Prolog, it's impossible to distinguish between
a constant and a predicate symbol or, indeed, between predicates with 0
arguments and constants. Perhaps as a result of this, Prolog accepts
predicates as arguments to predicates - since it can't distinguish between
0-arity predicates and constants, it has to accept predicates as arguments,
but then, it has to accept n-arity predicates as arguments. Which means that,
in principle, it's a FOL language, but in practice, it is actually
second-order. Maybe then the reason why predicates are known as "terms" in
Prolog is because they can, actually, take the place of terms. But, I don't
know for sure.
Anyway, there's a lot of terminlogical confusion around Prolog :)
This sentence on the front page succinctly tells me exactly what to expect: the main programming paradigm (logic, functional) and its main strength (performant declarative programming). So I can imagine the language pretty well. I might not know the syntax at all, but yet I can imagine, on an AST level, how known snippets might look like. In any case showing a snippet of Hello World doesn't say much about the language itself; it at best conveys some information about syntactic choices that one gets used to very quickly.
In order to understand this value proposition, you have to know what logic programming, functional programming, and declarative programming are and the relative strengths and weaknesses of each. Also it has a bunch of qualifiers that don't add much to the description. I know what static analysis is, but what is advanced static analysis? You also seem to have intuited that the language is performant, but that is not at all implied here.
A better statement to me would convey exactly what kind of workloads I might want to use Mercury for. As a user, I have something I want to get done, be that processing data, writing a game, or writing a network driver. I don't care about static analysis or logic programming per se. But I would if you told me it would make writing my game easier.
Plenty of people got something out of that page.
Here, I'll give it a shot:
"Mercury is a general purpose logic programming language that supports the development of large, reliable, efficient applications through static program analysis and a tunable execution algorithm"
From this one sentence I get the what (logic programming) why (for large reliable apps) and how (static analysis, customizable execution). Now I'm interested.
In theory, that sounds nice. Have you spent a year on Rust, Go, Elm, and Crystal? If not, then what if one of them is the perfect language for that problem you're trying to solve? How can you make the right judgment call when starting a project if you haven't spent a year using each of these and more?
In reality, that's a completely absurd approach for the first-level approximation people need/want when they discover a new language... surely you realize this. People need to be able to see the big picture before they'll know whether they want to dive into the details.
There are literally thousands of programming languages. Many are created each year. How can anyone afford to spend a year, full-time, on each language to discover the truth of each language? They can't.
So I agree with dotdi:
> Unfortunately, the documentation, FAQ and User Guide all failed in succinctly giving me the information I need: what can it do well, what does a known snippet look like implemented in <Lang>, how does it compare to other languages, etc.
Picking an obscure language that none of your developers know well is usually not the right decision, even if the language has certain advantages over the ones you already know.
Let's also not forget that, just because someone understands how to design and implement a really cool programming language, doesn't mean they understand how to perform "marketing and good communication". And vice-versa. These are often very different skillsets, like designing a racing car and actually racing it.
Again, it's not a given that a small team will have both those sets of skills readily at hand. Which of course, can stunt its growth, further compounding the problem.
I tried reading the docs (in the html version), and the first example is in the fourth or fifth page.
:- module hello.
:- import_module io.
:- pred main(io::di, io::uo) is det.
main(IOState_in, IOState_out) :-
io.write_string("Hello, World!\n", IOState_in, IOState_out).
Mercury also has HTML documentation, which is the way to go. However it's missing code samples in the home page and it's not like everybody knows about Mercury. Compare to https://www.ruby-lang.org/en/ which instead is pretty well known and still has code to show at the very beginning of the home page.
It doesn't have to be hard evidence exactly, but if you're claiming that something is easy, fast, "modern", what makes it so?
I concede that you can get away with it to some extent by splicing in "intended to be" in the sentence, but it still places on the visitor the burden of figuring out the "why" behind the marketing.
Most devs don't have the time to pick up esoteric hobbyist languages because they're clever.
I completely agree. But you also have to at least try to sell it to me. I don't have time to download the compiler, try some examples, build a little side project to find out "nope, don't like it".
What snippet in a purely functional programming language would be simultaneously intelligible and communicate the power of FP to someone who knew only imperative programming? I can't think of a single one that would be meaningfully representative of idiomatic FP. Making sense of FP from IP requires hard work to change your thinking on control flow and data flow.
Mercury is a constraint logic programming language. It's a fundamentally different paradigm, so you're asking for something exactly like what I described above. If you're familiar with constraint LP, then you don't need this sort of snippet, and if you're not familiar with it, I don't think any such snippet would be intelligible to you without hard work.
Propaganda about "the power of FP" was not what your parent was asking for. They were asking for code snippets. They were not asking for a program that shows off all the power of the language.
For whatever it's worth, here is Fibonacci: http://rosettacode.org/wiki/Fibonacci_sequence#Mercury and FizzBuzz: http://rosettacode.org/wiki/FizzBuzz#Mercury
> Mercury is a constraint logic programming language.
Nope. No constraints here. Also, you can mostly ignore the logic part and use it like a functional programming language.
Talk about missing the main point of my comment. Code snippets that simply embed other paradigms are typically non-idiomatic or just syntactic noise if you're not familiar with the syntax. Code snippets that show off the problems for which the language is perfectly suited are unintelligible to those that don't understand the paradigm. Code snippets simply aren't all that useful if your language has a fundamentally different paradigm.
> Nope. No constraints here.
Strange because they published a paper about adding constraints years ago .
I didn't miss your point. Your point was invalid. You were assuming that OP was entirely unfamiliar with functional or logic programming, and that functional or logic programming snippets would be unintelligible to them. You had no reason for these assumptions.
> Strange because they published a paper about adding constraints years ago
Ah thanks, I did not know that. The point above still stands, though: Adding an extension to what calls itself a "logic/functional" language does not make it into only a constraint logic programming language.
No I didn't. I exhaustively covered all cases: "If you're familiar with constraint LP, then you don't need this sort of snippet, and if you're not familiar with it, I don't think any such snippet would be intelligible to you without hard work."
The first clause says that the high-level description as a LP language suffices if you're already familiar with such a concept and so snippets aren't of much use, and if you're not, then a snippet wouldn't help you anyway.
Snippets would be useful for people who already know functional or logic programming. Have a nice day.
Seriously? I merely quoted my original text to demonstrate a completely unrelated point, so you're the one harping on this unnecessarily.
> Also, before, you were going on about functional programming as if OP was not familiar with it: "What snippet in a purely functional programming language would be simultaneously intelligible and communicate the power of FP to someone who knew only imperative programming?"
Right, the point being made is clarified by the text I quoted. If you're familiar with it then you don't need it, and if you're not then it wouldn't help you.
Mercury's selling poings are:
- runtime performance (automatic parallelization, very efficient due to logic programming understanding and rewriting sequenced operations)
- static typing (in an ml style / like OCaml)
- logic programming (unification of lvars)
As a language it fills an interesting niche as logic progamming language typically aren't dyanmically typed or high performance (ie Prolog, most miniKanren implementations).
Paul Bone has some good talks on Mercury if youre interested (heres some slides from an intro talk to Mercury https://paul.bone.id.au/pub/pbone-2015-mercury.pdf)
New members are more than welcome! Mercury is an interesting language, and it would be nice to bring enthusiasts a bit closer together.
- SCWM, Pot and the GPL (the Ratpoison Manifesto)
- A Brief, Incomplete, and Mostly Wrong History of Programming Languages
> The benchmarks were run on a Sun SPARCserver 1000 with four 50 MHz TI SuperSPARC processors and 256 megabytes of memory running SunOS 5.3 (Solaris 2.3). Each processor is rated at 60.3 SPECint92, and has a 4-way associative 16 Kb I-cache and a 5-way associative 20 Kb D-cache, backed by 1 Mb of unified secondary cache.
What's the rationale behind such antiquated benchmarking system? Interesting.
There are a lot of factors that can influence a modern system and most of them seem hard to control. For a 8086 you could probably account for all these factors if you put in the hours and run it in a highly controlled environment but I doubt its even possible for a modern CPU, let alone the whole system.
Of course this isn't a problem for most benchmarks as most of them are only useful for demonstrating real world use-cases where the variance is expected and the goal is not to benchmark the performance of a single element of the system but the perceived performance you can expect in a real-world scenario.
Or its simply designed by someone who loves this kind of system and found a good excuse to put one to use.
Its compiler is impressive, and is capable of acts such as compiling certain non-tail-recursive functions in a tail-recursive manner, or even transforming them into tail-recursive equivalents, given the right hints.
All this capability comes at a cost. At least as of ~4 years ago, the error messages the compiler can spit out over modality errors dwarf even those from C++ templates. And compiler bugs/unimplemented features are not unheard of.
I wanted to learn it recently, but couldn't find enough example programs.
It's a pretty handy general purpose language, kind of a combination of Prolog and Haskell. It's much easier to maintain a long-lived project in Mercury than one in Prolog due to the static typing, and it also generates much more efficient code. That said, it doesn't have the greatest documentation, so you might have to reach out on IRC, or the mailing list if you run into some challenges with it.
That aside, it's a pretty nifty language and I found learning it worthwhile.
Quite influential in those times ("typed prolog" with a better compiler), but didn't gain that much attention and some mercury projects were rewritten then in other languages.
But I suppose that's not really the most important factor of a language and the syntax could be fun to try out.
I don’t remember too much, but my prof. thought it was cool.