remix logo

Hacker Remix

Curry: A functional logic programming language

149 points by hyperbrainer 19 hours ago | 34 comments

abathologist 18 hours ago

Any one know how Curry (which has a Haskell-like syntax extended to support prologish features) compares with Mercury (which has a Prolog-like syntax extended to support Haskellish features)?

sterlind 17 hours ago

Mercury feels like if the Ada people wrote Prolog. it's very verbose. you have to declare signatures in separate files and determinism modes. grounding is strictly enforced. it's statically typed. there's no REPL, remarkably.

in exchange, the compiler catches a lot of bugs and the code is blazing fast.

Curry is a superset of Haskell. it takes Haskell's pattern matching and makes it extremely general (full unification), extends it to non-determinism with choice points. it does have a REPL, like ghci.

Like Haskell, Curry is lazy. Mercury (like Prolog) uses mostly eager, depth-first evaluation (SLDNF resolution.) Clause order doesn't matter in Curry, which uses a strategy of "needed narrowing" - variables are narrowed when they need to be.

Unlike Mercury (and Prolog), and like Haskell and other FP languages, Curry draws a distinction between function inputs and outputs. You can do relational programming via guards and pattern matching, but it doesn't feel as Prolog-y.

Curry is more niche than Mercury, which is at least being used to build Souffle (a static analysis language built on Datalog), which is actually being used in industry somewhat. But it's a shame because Curry has a lot to offer, especially to Haskellers. They're both worth checking out though.

cess11 46 minutes ago

Last I dabbled in Mercury it generated C and compiled that, which I expect to make a REPL harder to achieve compared with a ghci adjacent environment.

fuzztester 7 hours ago

Mercury was used to build Prince (XML), a commercial PDF generation product.

https://en.m.wikipedia.org/wiki/Prince_(software)

hyperbrainer 17 hours ago

Not a technical difference, but I think Mercury is somewhat more "commerical" in that it's out of development and can be used in real projects, compared to Curry, which is very much in development.

badmonster 19 hours ago

How does Curry manage ambiguity in non-deterministic computations—especially when multiple valid instantiations exist for a free variable?

pjmlp 18 hours ago

Probably like Prolog, we get to generate all possible variations.

taeric 13 hours ago

That example for "some permutation" is not at all easy for me to understand. I'm assuming I'm just not familiar with the general style?

idle_zealot 13 hours ago

I'm unfamiliar as well, but my best guess is that it relies on non-determinism. i.e. both definitions of 'insert' might be valid, and the runtime chooses which to use at random, resulting in either x or y being prepended to the returned list.

sterlind 12 hours ago

it's not random. it tries definitions in declaration order until one succeeds. it's then yielded as an assignment of variables and control returns to the caller. if that assignment gets contradicted it will backtrack and try the second definition, so on and so forth. it's more like coroutining.

taeric 12 hours ago

Does this definition somehow cause all random permutations of a given list? The definition of "Some Permutation" seems to imply it can be used any place you need to try any/all permutations, one at a time? At the least, repeated calls to this would be different permutations?

sterlind 9 hours ago

quick Prolog example because I'm not as familiar with Curry:

% This generates or recognizes any palindrome: pal --> [_]. pal --> X,pal,X.

% Here we try it out and press ; to generate more answers. ?- phrase(pal,P). P = [A]; P = [B,A,B]; ...

% Here we plug in a value and it fails with [A], fails with [B,A,B], etc. until it gets to [D,C,B,A,B,C,D], which can be unified with "racecar." ?- phrase(pal, "racecar") true.

Another example is just (X=a;X=b),(Y=b;Y=a),X=Y. This has two answers: X=a, Y=a, and X=b,Y=b. What happens is that it first tries X=a, then moves onto the second clause and tries Y=b, then moves onto the third clause and fails, because a≠b! So we backtrack to the last choicepoint, and try Y=a, which succeeds. If we tell Prolog we want more answers (by typing ;) we have exhausted both options of Y, so we'll go back to the first clause and try X=b, then start afresh with Y again (Y=b), and we get the second solution.

Prolog goes in order, and goes deep. This is notoriously problematic, because it's incomplete. Curry only evaluates choicepoints that a function's output depends on, and only when that output is needed. Curry does have disjunctions (using ? rather than Prolog's ;), unification (by =:= rather than =), and pattern guards rather than clause heads, and the evaluation strategy is different because laziness, but in terms of the fundamentals this is what "non-determinism" means in logic programming. it doesn't mean random, it means decisions are left to the machine to satisfy your constraints.

YeGoblynQueenne 2 hours ago

>> ?- phrase(pal, "racecar") true.

Off the top of my head but I think that should be backticks, not double quotes? So that `racecar` is read as a list of characters? I might try it later.

>> Prolog goes in order, and goes deep. This is notoriously problematic, because it's incomplete.

Yes, because it can get stuck in left-recursive loops. On the upside that makes it fast and light-weight in terms of memory use. Tabled execution with memoization (a.k.a. SLG-Resolution) avoids incompleteness but trades off time for space so you now risk running out of RAM. There's no perfect solution.

Welcome to classical AI. Note the motto over the threshold: "Soundness, completeness, efficiency: choose two".

cess11 49 minutes ago

To me --> looks like DCG and should work with ", if whatever the flag is called, is set. Scryer has it set by default now, I think. At least it was some time ago I had to look it up and set it myself.

otherayden 16 hours ago

Imagine having your first and last names turn into two separate programming languages lol

Qem 13 hours ago

mikhailfranco 6 hours ago

Pascal was not Blaisingly fast.

crvdgc 8 hours ago

They meant to name Haskell the programming language Curry at first, but the proposal was struk down because of the potential association with Tim Curry.

https://youtu.be/LnX3B9oaKzw?t=3m6s

lud_lite 11 hours ago

Lovelace would be a great language name someone should use it.

a3w 2 hours ago

cursory glance: http://lovelace-lang.org/ is even free