zlacker

[return to "Can logic programming be liberated from predicates and backtracking? [pdf]"]
1. woolio+du2[view] [source] 2024-10-13 08:10:44
>>matt_d+(OP)
This is a reference to the "Can programming be liberated from the von Neumann style?" from 1977. It argues for functional programming, making the point that the imperative style is more common for efficiency reasons, as the programming model is close to the computer architecture. It aims to be a general thought framework inviting to step a step back on some notions that have been (hastily?) accepted in the programming world.

It makes the same analogy that Prolog (or logic programming languages in general) have been strongly influenced by the resolution algorithm. In practice that means that if you write a non-trivial program, if performance is not right you'll need to understand the execution model and adapt to it, mainly with the pruning operator (!). So while the promise is to "declare" values and not think about the implementation details, you're railroaded to think in a very specific way.

I personally found that frustrating to find good solutions essentially unworkable because of this, in comparison with either imperative or functional paradigms that are significantly more flexible. As a result, Prolog-style programming feels limited to the small problems for which it is readily a good fit, to be integrated into a general program using a general-purpose language. I may be wrong on this, but of the 50 people that learned Prolog around the same time as me, none kept up with it. Meanwhile, other niche languages like Ocaml, Haskell and Scheme had good success.

Rethinking the language foundation could remove these barriers to give the language a broader user base.

◧◩
2. PaulHo+yX2[view] [source] 2024-10-13 13:38:24
>>woolio+du2
The way you write imperative programs in Prolog by exploiting the search order, using cuts, etc. seems clever when you see it in school and do a few assignments for a comparative programming languages class (the only 3 credit CS course I took) but it is painfully awkward if you have to do very much of it.
◧◩◪
3. YeGobl+E53[view] [source] 2024-10-13 14:41:16
>>PaulHo+yX2
It isn't. I do most of my programming in Prolog, I write oodles of it daily, and it's not a problem. You learn to think that way easily.

The argument is basically that Prolog is not 100% declarative and that if we jump through a few hoops, and translate it all to functional notation, we can make it "more declarative". But let's instead compare the incomplete declarativeness of Prolog to a fully-imperative, zero-declarative language like Python or C#. We'll find I believe that most programmers are perfectly fine programming completely non-declaratively and don't have any trouble writing very complex programs in it, and that "OMG my language is not purely declarative" is the least of their problems. I hear some old, wizened nerds even manage to program in C where you actually can drop to the hardware level and push bits around registers entirely by hand O.o

◧◩◪◨
4. upghos+Se3[view] [source] 2024-10-13 15:48:24
>>YeGobl+E53
Serious question, how do you deal with typos in functors? And is your techniques specific to the implementation of Prolog you use? Recently I had a maddening experience chasing this down:

  result(World0, move(robot(R), Dir), World) :-
        dissoc(World0, at(robot(R), X0), World1),
        direction_modifier(Dir, Modifier),
        X #= X0+Modifier,
        conj(World1, at(robot(R), X), World).
  result(World0, drop_rock(robot(R), Place), World) :-
        dissoc(World0, capacity(Place, Capacity0), World1),
        dissoc(World1, carring_rock(robot(R)), World2),
        Capacity #= Capacity0 + 1,
        conj(World2, capacity(Place, Capacity), World).
  result(World0, pickup_rock(robot(R), Place), World) :-
        dissoc(World0, capacity(Place, Capacity0), World1),
        Capacity #= Capacity0 - 1,
        conj(World1, capacity(Place, Capacity), World2),
        conj(World2, carrying_rock(robot(R)), World).

See if you can spot the bug.

...

...

...

  carrying_rock vs carring_rock

Because the typo was in a functor (not predicate or singleton variable) there was no IDE or language support, Prolog assumed that I wanted an reported the wrong answer. of course the snippet I showed was part of a larger example. In other languages it would've taken me 5 minutes to bisect the program or debug and find the error but it took me 3-4 hours. I ended up needing to write a lot of error correcting code, basically a half-assed type system, and that code ended up being more substantial than the actual program logic. Is this common? Am I "doing it wring"?

Right now this seems to have all the downsides of programming exclusively with "magic strings", and I haven't been able to find any cure for it or even seen this problem discussed elsewhere.

*Edit:*

I even rewrote it for SICStus and downloaded their IDE and taught myself Eclipse just to use their IDE plugin, and found that setting breakpoints didn't help the problem, because naturally due to the fact that the functor is in the predicate signature, the predicate is never stepped into in the first place!

I could linearize the arguments and include them in the body but this destroys the indexing and can put me into "defaulty representation" territory.

◧◩◪◨⬒
5. foobie+iP3[view] [source] 2024-10-13 20:23:20
>>upghos+Se3
so so so so so so so so so much this. I have tried to make prolog a part of various systems on and off for two decades and the ergonomics and basic practical shit like this is why it never works.

the answer is always: do a lot of manual stuff that the language should do for you. I can, but I can't get a team to.

◧◩◪◨⬒⬓
6. YeGobl+IP3[view] [source] 2024-10-13 20:26:57
>>foobie+iP3
Then don't use Prolog. It's not mandatory.

For the record I never have problems like that and I'm sure I'm not special. Well, not in that way. This all comes under the heading of "learn what works". You have to do that with any language.

Edit: as a slightly less flippant answer (sorry) Prolog doesn't "do a lot of manual stuff that the language should do for you" because the Prolog community doesn't think the language should do those things for you and I agree. Take for instance inheritance and composition, like in object orientation. There's no reason Prolog should do that for you. If it did, it would shoehorn you into a certain programming paradigm that can feel like a straightjacket when you don't need it, but you absolutely need to use it because that's what the "language does for you". Prolog instead gives you the tools to do all the things you need, when you need them. It's more work, for sure, but it's also more freedom. I spent most of my career in the industry working with very rigidly OOP languages and that's one reason why I escaped into academia, where I can program in Prolog (see what I did there?) all day without having to declare a class property if I don't want to. And if I really wanted to, I could go all the way and write something like Logtalk:

https://logtalk.org/

Another example of something that Prolog doesn't do for you, and that you don't always need, but can always do yourself if you need it, is typing; like I point out in the sibling comment. Why should Prolog do that for you? Are we going to have the whole argument about strongly typed vs. weakly typed languages all over again? I think not. If you want types in Prolog, you can roll your own. Now try to write, say, C# code without types, when you really don't need the bother.

◧◩◪◨⬒⬓⬔
7. foobie+Tl7[view] [source] 2024-10-15 03:57:59
>>YeGobl+IP3
You can never roll your own and have a working ecosystem. This is exactly the problem.
[go to top]