5 ms·
My opinion: Humans are good at thinking sequentially, imperatively. Other language paradigms are harder. That isn't to say that Functional languages (Lisp, Has
by mabbo 9y ago
My opinion: Humans are good at thinking sequentially, imperatively. Other language paradigms are harder.
That isn't to say that Functional languages (Lisp, Haskell, Scala, etc) aren't as good; frankly, I like them better. There's just a mental gap that has to be crossed and for most developers I've met, that can be challenging. Why do things in a challenging way when I've got Java right here and it works just fine? (straw man, not my own view)
Prolog (logic programming) is a bigger gap, imho. It takes more effort for me to really understand Prolog code. Can do some beautiful things with it, but it's easier to have a few good developers be good at it and put their hard work behind a library/API than it is to have every other developer try to get over that gap.
- jdc 9y agoIt seems to me that people whose first language is imperative often find thinking imperatively easier to do.
- mpfundstein 9y agodon't know. My first language was C++. For years actually. Then I learned Clojure, went to University, learned Prolog, Haskell etc.. and essentially turned out to become a FP geek. But it was a difficult road to climb. :-)
- ambrop7 9y agoI don't think there's really a "functional gap". All generally useful programming languages including Prolog are imperative "in the end" no matter what the books say, and anyone good at using them will think about the programs imperatively. The language just has "special features" such as ones that go like "try to match this with that and examine each possibility separately". If you try to write Prolog by "describing" the solution instead of thinking about the steps to achieve it, the code will likely not work at all (infinite recursion) or be very inefficient, in spite of being logically correct. What may look like a "functional gap" may just be the lack of ability for abstract thought, and more correlated with (in)ability to write well structured and generally "nice" code, especially to identify common patterns and create reusable code. Because functional/logical is just an implementation of some abstract pattern that is believed to be useful, and the person may have trouble understanding this pattern just as they would have problems understanding existing abstractions or creating their own abstractions.
- tom_mellior 9y agoI think you're over-simplifying things if you say that not understanding Prolog programs comes down to a "lack of ability for abstract thought". You can think abstractly all you want, that will not help you if you don't know by heart the sometimes arcane rules of setting choice points and binding variables. Those are not things that you can work out on your own, thinking abstractly; those are concrete rules chosen by people over a period of 40 years. The converse is true, of course: A person that cannot write well structured and "nice" code in other languages won't be able to magically do that in Prolog either.
- westoncb 9y agoPart of the problem may just be that languages like Prolog are still leaky abstractions at this point—you still have to consider how it's doing what it's doing, performance consequences etc. In principle, you should be able to use such a language to merely describe what it is you want (and let the language find/construct it), while with an imperative language you have to specify precisely how it will be produced. Seems like the other difficulty is that its 'interface' (programmer facing portions of the language) derive from mathematical ideas which will already be very familiar to those working in the field, so it's very convenient for them, while for those outside mathematics (and more theoretical parts of CS) there will be surprising gaps when attempting to learn because of the implicit mathematical concepts in the interface. For instance, Prolog is based on Horn clauses[0], a subset of first order predicate logic. Additionally, 'relations' are a central part of the language's interface—and if you have a background in pure math, this is great for you because it immediately tells you all kinds of things; if you don't, it's going to be confusing because much of the literature will assume you have similar experience reasoning about relations. Seems like it would be possible to move those concepts out of the interface, while still using them in the internals... [0] https://en.wikipedia.org/wiki/Horn_clause https://en.wikipedia.org/wiki/Horn_clause
- mst 9y agoI've been quite fascinated by answer set programming, because unlike prolog its clauses are unordered which give the language the opportunity to significantly optimise execution - though at the cost that, as with haskell, it's often quite tricky to reason about what you just did that caused a performance issue.
- ThrowawayR2 9y ago> My opinion: Humans are good at thinking sequentially, imperatively. It's more basic than that. The underlying CPU is unabashedly sequential and imperative. It even uses (shock, horror) bare GOTOs, i.e. conditional and unconditional jump instructions. These other models might be more mathematically elegant in some abstract sense, sure, but I'd rather work with the underlying hardware than fight against it.
- tom_mellior 9y agoIf you think that functional and logic-oriented programming languages "fight against" the hardware, you may have missed a few decades of developments in efficient compilation and interpretation of such languages. Hint: Internally, they use (shock, horror) GOTOs just like other programming languages, to the same effect.
- nickpsecurity 9y agoThe major ones usually target an abstract machine or intermediate language which is implemented in low-level ways. Those abstract or intermediate languages help the logic and function oriented languages compile easier. I'd love to see them go straight from high-level Haskel or Prolog to LLVM bytecode with LLVM's optimizations handling the rest. That would be interesting in light of your comment. Instead, the intermediate, abstract forms remain out of utility or necessity.
- tom_mellior 9y agoLLVM bitcode is too low-level for many of the optimizations, such as deforestation and similar optimizations of functional programs. It is useful for later, low-level things, and there is a good LLVM backend for GHC. At the same time, LLVM is too high-level for some other things, such as Prolog's particular brands of stack unwinding and indirect jumps on backtracking.
- nickpsecurity 9y agoThe first was expected. The second on Prolog optimizations was interesting.
- threepipeproblm 9y agoI think you are right despite the backlash you are getting. In college I got deep enough into Prolog to write programs where cuts were required. Later, I got excited about miniKanren. Now I've been looking into constraint programming, and what I didn't understand until recently is that it basically generalizes the Prolog techniques to handle any kind of equation solving / relational search approach. You can do amazing stuff with these systems (e.g. look at HAL http://users.monash.edu/~mbanda/hal/ http://users.monash.edu/~mbanda/hal/), including write custom search algorithms (consider classic Prolog unification just 1 search strategy on a limited domain). But I don't think there is any getting around the fact that this stuff gets conceptually harder, as it gets more powerful. The idea of solution sets as potentially infinite relations, rather than functionally determined things, is very powerful but there is an abstraction price. And to the extent people can wrap their heads around it, there is a "letting go" in not writing programs in the style of deterministic algebraic manipulations. Part of this may reflect a bias, but the magic of delegating solution-finding to an algorithm is also dangerous. Are you comfortable not knowing how many answers there might be if you let the program keep running? Similarly, consider Prolog's negation as failure. You can't express many formulas that you might like to involving "NOT". Negation is interpreted as a program just not returning anything. There are important reasons for this model, but again, it isn't necessarily as easy a model where NOT can be used freely. BTW not many people seem to know that Japan had a huge, Manhattan-style program in the 80's. They made Prolog their lower tier.. like their assembly language, or close to it (this was back when people were still thinking different computing platforms needed different hardware). Some people ultimately blamed Prolog for what is generally regarded as the failure of this "fifth generation" project to leapfrog Western tech. But I think Prolog suffered unduly as a result. In fact that project was trying to to a bunch of ambitious things and they all hung on one another. For example, they were trying to make speech the UI, with 80's tech... All this said I would encourage anyone to explore Prolog, miniKanren, Mercury, Shen or anything of that ilk.
- zmonx 9y agoYour post is full of good insights, and I also highly recommend these pointers and environments! I only want to briefly comment on the question "Are you comfortable not knowing how many answers there might be if you let the program keep running?", which I think is well worth thinking about. If you really think about this, then the most interesting programs you can write typically have this property, because they search for things that we do not even know exist, such as new theorems, some structures with unique properties, or even mistakes and race conditions in programs! Also, in my experience, the more you focus on declarative properties and fundamental principles such as termination, the easier it gets to apply Prolog in practice. The difficulties I have seen many beginners struggle with often arise from trying to reason about Prolog programs in the way they reason about imperative programs, which indeed gets too hard to do in practice very quickly. In contrast, if you think in terms of generalizations and specializations, and program fragments, you can reason much more easily about Prolog programs in practice. However, it requires that you stay in the pure monotonic core of the language, of which constraints are also a subset.
- SeanLuke 9y agoI think you're right. The promise of Prolog was that you'd be able to just define the task requirements, then write the requirements in Prolog and magic would happen. But even the most experienced Prolog coders I know don't really think in Prolog. When faced with a coding task, they inevitably first (mentally) figure out the problem in an imperative form, perhaps with some recursion, and then they they ask themselves "okay, how do I convert that to logic and pattern-matching?" If you're going to go through that process, then Prolog provides no value: it's just an extra step, and you might as well code in C (okay, Lisp). I fear that Haskell will turn out the same way. After all monads are just monoids in the category of endofunctors, right?
- nv-vn 9y agoThis is really dependent on the programmers background and what they're writing. Some code is super easy to write in Prolog and much harder in any other languages. Take type inference algorithms for example. Rather than describing how to solve it, you just translate the typing rules directly to Prolog clauses. Thinking about imperative problems is hard in Prolog and will make you think backwards. Thinking about logic problems in C is the same way.
- zmonx 9y agoI second this. When writing Prolog programs, the more you think procedurally, the more specific your programs will become in the sense that you can then typically only use them in specific directions. To make your Prolog code as general as you can, I recommend to also think in terms of relations. This definitely takes effort, which pays off in the increased generality.
- mst 9y agoInteresting - I know a number of people who think in prolog, and when faced with a task that it's well suited for I often mentally figure out the problem in prolog form, and then ask myself "okay, how do I convert that to normal code?" Happens with lisp as well - I barely ever write prolog or lisp but I regularly think in them first before writing the solution in another language.
- 9y ago
- flavio81 9y agoThat's why it is such a good thing to use a true multi-paradigm language. The power resides in being able to express your problem using the paradigm that makes you solve it in the best way. For example you can implement a subset of Prolog inside Common Lisp, and thus you can employ the following paradigms as you wish: - Imperative - Functional - Object Oriented - Logic Programming For me, in year 2017, a programming language that implements only one paradigm, for example Haskell (almost a purely functional language), can't be considered a "general-purpose" language. Quite the opposite, it is a very specialized language, and it will work great for the problem domains where such paradigm fits perfectly into.
- aerovistae 9y ago> A straw man is a common form of argument and is an informal fallacy based on giving the impression of refuting an opponent's argument, while refuting an argument that was not advanced by that opponent. > Why do things in a challenging way when I've got Java right here and it works just fine? How is that a straw man? If an individual were to say that, in what way are they refuting an argument you didn't advance?
- twitchard 9y agoThe "straw man" in the straw man fallacy is the argument that nobody is making. The comment about "Java is right here" is not a straw man fallacy -- but it is a straw man.
- aerovistae 9y agoI'm sorry, genuine question, I'm still not seeing how that's a straw man. How is "Java is right here" an argument nobody is making? He's using it as an argument himself to question the value of working with a functional language, no?
- twitchard 9y agoSorry -- more precisely a "straw man" is usually an argument which you do not advocate yourself, that you construct -- usually in order to argue against it and strengthen your own position. When the author of the comment says "straw man, not my own view" in parentheses, he is saying "hey, this is what I imagine somebody who likes Java and not functional languages might think".
- 75dvtwin 9y agoI think prolog was a bit ahead of its time. Just like Lisp was ahead of its time in the 80s. Just like Erlang was ahead of its time but much more viable now. My issue with Prolog is not being able to easily conceptualize 'simpler things' -- like parsing text-based data structures, processing arguments, reacting to errors at various levels of interactions with OS or Databases or or other (micro) services. I believe, overtime as we learn how to define programs in ways that allow to confirm program correctness, models like Prolog's will become more and more prevalent. Because, in my subjective view, proving correctness of declarative expressions is much simpler and more effective than proving correctness of 'implementation directives'.
- brutus1213 9y agoI think you are right. I wondered the same thing about functional programming ala ML, LISP, etc. about 15 years ago. Today, "functional" is all the range and the paradigm is finding its way into mainstream languages. I think the same will happen for logic programming ala Prolog. That said, I have seen a lot of hostility towards rule-based systems in the last 2-3 years ... it is nonsensical IMHO.
- 75dvtwin 9y agoI think prolog was a bit ahead of its time. Just like Lisp was ahead of its time in the 80s. Just like Erlang was ahead of its time but much more viable now. My issue with Prolog is not being able to easily conceptualize 'simpler things' -- like parsing text-based data structures, processing arguments, reacting to errors at various levels of interactions with OS or Databases or or other (micro) services. I believe, overtime as we learn how to define programs in ways that allow to confirm program correctness, models like Prolog's will become more and more prevalent. Because, in my subjective view, proving correctness of declarative expressions is much simpler and more effective than proving correctness of 'implementation directives'.