4 ms·
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 basica
by YeGoblynQueenne 2y ago
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
- Pearledlang 2y agoReally interesting to hear! I was quite hooked to Prolog in a previous life. Then the limiting factor was the tooling, for really practical use. Could you tell a bit about your Prolog environment?
- agumonkey 2y agoseconded
- YeGoblynQueenne 2y agoI use the SWI-Prolog IDE: https://www.swi-prolog.org/PceEmacs.html https://www.swi-prolog.org/PceEmacs.html I suppose it is a bit spartan, but it has a ton of functionality that I find indispensable [1]. For example, when I place my cursor on a variable in the editor it highlights all the variables that unify with it in the same clause, and it will highlight singleton variables in a different colour so you can catch errors caused by typos easily. It is also aware of things like imported predicates, undefined or dynamic predicates, multi-file predicates etc, and will highlight them accordingly. It has some (limited) auto-complete and code-expansion etc. and a status line that gives you very good information about the kind of term you have your cursor on - where it's defined if it's a predicate, its name and arity and how many clauses etc, basically much of the information you can get from querying the program database with various program inspection built-ins. Some of my colleagues use VS Code to write Prolog instead and I keep shaking my head and grumbling about the errors they keep making that they wouldn't if they used the SWI-Prolog IDE instead. Kids, these days. In my youth, we wrote all our Prolog on Notepad! And compiled on Dos! (nope. never) SWI also has a graphical debugger, which however I never use: https://www.swi-prolog.org/pldoc/doc/_SWI_/xpce/prolog/lib/gui_tracer.pl https://www.swi-prolog.org/pldoc/doc/_SWI_/xpce/prolog/lib/g... I know some people swear by its name but I prefer the textual debugger. Again this one looks a little spartan :) More goodies in SWI: cross-referencer: https://www.swi-prolog.org/gxref.md https://www.swi-prolog.org/gxref.md And profiler: 1 ?- profile(between(1,10,_)). ===================================================================== Total time: 0.000 seconds ===================================================================== Predicate Box Entries = Calls+Redos Time ===================================================================== between/3 1 = 1+0 0.0% true. And lots and tons of facilities for debugging and error handling, unit testing, all sorts of libraries, a package manager etc. ________________________ [1] You can customise the IDE colours too. There's a dark theme: https://www.swi-prolog.org/pldoc/man?section=theme https://www.swi-prolog.org/pldoc/man?section=theme There's some screenshots here: https://swi-prolog.discourse.group/t/questions-about-ide-themes/6817 https://swi-prolog.discourse.group/t/questions-about-ide-the...
- nextos 2y agoDo you use Prolog in Academia or you have moved to Industry?
- YeGoblynQueenne 2y agoI moved to academia, after six years of working in the industry mainly with C# and SQL. It was a deliberate attempt to find a way to work with Prolog. I guess that's a bit immature of me but I fell in love with Prolog in the second year of my CS degree and I couldn't get over it so here I am. I did an MSc in data science first, then started a PhD to study Inductive Logic Programming (ILP), which is basically machine learning × Prolog (although there's also ASP ILP these days). I got my PhD last summer and I'm now doing a post-doc on a robotics project with Meta-Interpretive Learning (MIL), a recent form of ILP. Here's my latest publication: https://github.com/stassa/ijclr_2024_experiments https://github.com/stassa/ijclr_2024_experiments Which is still a bit proof-of-concept. We're still at the very early stages of practical applications of MIL and so there's a lot of foundation work to do. Bliss :)
- cryptonector 2y agoYou might want to look at the Icon programming language. I fell in love with it long ago, but I did not go the academic route to use it more, I just accepted that it wouldn't be a part of my work life. Later -much later- I found jq, with which I had more success in industry. Both are very much like logic programming languages in that they have pervasive (DFS) backtracking.
- YeGoblynQueenne 2y agoOh, I see Icon is a descendant of SNOBOL. I'll have a look, that seems interesting. Thanks for the pointer :)
- cryptonector 2y agoI hope you enjoy it! I sure did. If you enjoy it, you might also enjoy jq (https://github.com/jqlang/jq https://github.com/jqlang/jq), which is also a sort of logic programming language (in that it has pervasive generators and backtracking). Icon has an Algol family syntax, while jq is more... Haskell-ish? in a way if you squint hard? Whereas Prolog is a pile of rules. These differences are very interesting. Verse is another language in this vein, and it seems very interesting as well. Oh, and yesterday's HN thread about Rama is very interesting as well: https://news.ycombinator.com/item?id=41833629 https://news.ycombinator.com/item?id=41833629
- upghost 2y agoSerious 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.
- deleted 2y ago[deleted]
- YeGoblynQueenne 2y ago>> 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. The cure is to not try to program with "magic strings". You don't need to, and if you really want to, then you should try to understand what exactly it is that you're doing, and do it right. Specifically, what you call "magic strings" are what we call "functions" in First Order Logic, and that Prolog calls compound terms, like carring_rock(robot(R)) which is in fact two compound terms, nested. Prolog lets you nest compound terms infinitely and if you really want to hurt yourself, one great way to do it is to nest terms everywhere. The alternative is to understand that when you use compound terms as arguments to predicates (or other terms) you are really _typing_ those arguments. Above, "carring_rock(_)" is the type of the second argument of result/3, and "robot(_)" is the type of the single argument of carring_rock/1. The catch is, of course, that Prolog is not a typed language and it doesn't care if you want to hurt yourself. So if you need to have types like that, then you should write some code to explicitly handle types and do some type checking. For instance, right out the top of my head: result_type(T):- T =.. [carring_rock,R] ,robot_type(R) ,!. result_type(T):- throw('Unknwon result type':T) robot_type(T):- T =.. [robot,R] , % ... further typing of R ,!. robot_type(T):- throw('Unknown robot type':T) Note that this is not the right way to throw errors but I can't now. A simpler thing I'd advise, but that's going into style territory, is to keep variable names as short as possible. One reason it's hard to spot the mistake in the code above is that the source code is all cluttered with long variable names and the nesting of compound terms makes it even more cluttered. An IDE with good syntax highlighting can also help. Perversly, I find that there are many people who code in Prolog either without syntax highlighting at all or in IDEs that are not aware of common results of typos, like singleton variables. The SWI-Prolog IDE is good for this and Sweep for Emacs has a good reputation also (although I haven't tried it): https://eshelyaron.com/sweep.html https://eshelyaron.com/sweep.html Edit: it just occurred to me that the project I'm working on currently, in my post-doc, involves quite a bit of typing using compound terms as arguments, like you do above. I've opted for a program synthesis approach where the predicates I need with typing are automatically generated from a specification where I define the arguments of predicates' types. Doing the same thing by hand is probably my number two recommendation of how not to code in Prolog. Number one is "the dynamic database is evil", but does anyone listen to me? Never. Edit 2: Covington et al's Coding Guidelines for Prolog make the same point: 5.13 Develop your own ad hoc run-time type and mode checking system. Many problems during development (especially if the program is large and/or there are several developers involved) are caused by passing incorrect arguments. Even if the documentation is there to explain, for each predicate, which arguments are expected on entry and on successful exit, they can be, and all too often they are, overlooked or ignored. Moreover, when a “wrong” argument is passed, erratic be- havior can manifest itself far from where the mistake was made (and of course, following Murphy’s laws, at the most inconvenient time). In order to significantly mitigate such problems, do take the time to write your own predicates for checking the legality of arguments on entry to and on exit from your procedures. In the production version, the goals you added for these checks can be compiled away using goal_expansion/2. https://arxiv.org/abs/0911.2899 https://arxiv.org/abs/0911.2899 >> I could linearize the arguments and include them in the body but this destroys the indexing and can put me into "defaulty representation" territory. Sorry, I don't know what either of those are: "linearize the arguments" and "defaulty representation". Prolog only has first-argument indexing normally, although some implementations let you change that and use your own indexing scheme. Is that what you did?
- skybrian 2y agoI agree that not being fully declarative is okay. But lots of pure functions are written in languages like Python and C#. “Fully-imperative, zero-declarative” seems like a bit of an exaggeration? (I’m generally of the opinion that both laziness and backtracking are bad defaults for general-purpose programming, but they’re handy when you need them.)
- YeGoblynQueenne 2y agoSee sibling comment to dragonwriter- maybe I'm exaggerating a bit, but I think it's only a bit. It's been a while since I've programmed a lot in anything but Prolog so maybe I should be a little more circumspect.
- dragonwriter 2y ago> But let's instead compare the incomplete declarativeness of Prolog to a fully-imperative, zero-declarative language like Python or C#. There's no such thing as "fully-imperative, zero-declarative language" -- at least not one as high level C# or Python -- because declarative/imperative are programming styles, which languages can make more natural but which are used with all (well, higher-level than assembly) languages.
- YeGoblynQueenne 2y agoI think there are declarative elements in various high-level languages, e.g. Linq queries in C# so I guess it is an exageration to say "zero-declarative", but in general the level of declarative-ness is tiny compared to Prolog. Did I misunderstand what you mean?
- thesz 2y agoHave you tried Haskell? For example, it is possible to embed backtracking logic programming [1] into Haskell with not a big effort. [1] https://hackage.haskell.org/package/logict https://hackage.haskell.org/package/logict
- illogical_spock 2y agoIt sure is if you read enough "Functional Pearls" to think all you need for logic programming is some backtracking. Oh, and the cut. Because you can't control backtracking without the cut. Not if you don't understand what the backtracking is for in the first place! Mwahahaha. Oh sorry. Did I let my schadenfreude out again?