Does JParsec have an `until' combinator? - jparsec

An `until' combinator consumes input until the given parser has been satisfied.
I googled and gave a glimpse of the source of the Parser class, didn't find one. I think this combinator is common in every parser combinator framework in other languages.

Related

Why does JSONPath not support parent?

JSONPath seems to be a popular syntax to get XPath-like searching inside JSON data. And it has been repeatedly asked whether JSONPath supports navigation to a parent (see here and here).
My question is whether there is a good reason why it has not been suggested from the start, even though it is explicitly mentioned as unsupported. Is there some syntactic reason from JavaScript? Or is there some general workaround that I am missing?
This specification was written up on a blog; AFAIK, it is not part of any ongoing committee standardization.
However, to meet the need for parent accessors (and other features), at least one implementation, JSONPath-plus which is a superset of the original spec, allows for accessing parents through a number of means (see the README docs).
Disclaimer: I am involved in working on this implementation.

What is the difference between a combinator and a higher order function?

I have always thought the definition of both of these were functions that take other functions as arguments. I understand the domain of each is different, but what are their defining characteristics?
Well, let me try to kind of derive their defining characteristics from their different domains ;)
First of all, in their usual context combinators are higher order functions. But as it turns out, context is an important thing to keep in mind when talking about differences of these two terms:
Higher Order Functions
When we think of higher order functions, the first thing usually mentioned is "oh, they (also) take at least one function as an argument" (thinking of fold, etc)... as if they were something special because of that. Which - depending on context - they are.
Typical context: functional programming, haskell, any other (usually typed) language where functions are first class citizens (like when LINQ made C# even more awesome)
Focus: let the caller specify/customize some functionality of this function
Combinators
Combinators are somewhat special functions, primitive ones do not even mind what they are given as arguments (argument type often does not matter at all, so passing functions as arguments is not a problem at all). So can the identity-combinator also be called "higher order function"??? Formally: No, it does not need a function as argument! But hold on... in which context would you ever encounter/use combinators (like I, K, etc) instead of just implementing desired functionality "directly"? Answer: Well, in purely functional context!
This is not a law or something, but I can really not think of a situation where you would see actual combinators in a context where you suddenly pass pointers, hash-tables, etc. to a combinator... again, you can do that, but in such scenarios there should really be a better way than using combinators.
So based on this "weak" law of common sense - that you will work with combinators only in a purely functional context - they inherently are higher order functions. What else would you have available to pass as arguments? ;)
Combining combinators (by application only, of course - if you take it seriously) always gives new combinators that therefore also are higher order functions, again. Primitive combinators usually just represent some basic behaviour or operation (thinking of S, K, I, Y combinators) that you want to apply to something without using abstractions. But of course the definition of combinators does not limit them to that purpose!
Typical context: (untyped) lambda calculus, combinatory logic (surprise)
Focus: (structurally) combine existing combinators/"building blocks" to something new (e.g. using the Y-combinator to "add recursion" to something that is not recursive, yet)
Summary
Yes, as you can see, it might be more of a contextual/philosophical thing or about what you want to express: I would never call the K-combinator (definition: K = \a -> \b -> a) "higher order function" - although it is very likely that you will never see K being called with something else than functions, therefore "making" it a higher order function.
I hope this sort of answered your question - formally they certainly are not the same, but their defining characteristics are pretty similar - personally I think of combinators as functions used as higher order functions in their typical context (which usually is somewhere between special an weird).
EDIT: I have adjusted my answer a little bit since - as it turned out - it was slightly "biased" by personal experience/imression. :) To get an even better idea about correctly distinguishing combinators from HOFs, read the comments below!
EDIT2: Taking a look at HaskellWiki also gives a technical definition for combinators that is pretty far away from HOFs!

Explanation of combinators for the working man

What is a combinator??
Is it "a function or definition with no free variables" (as defined on SO)?
Or how about this: according to John Hughes in his well-known paper on Arrows, "a combinator is a function which builds program fragments from program fragments", which is advantageous because "... the programmer using combinators constructs much of the desired program automatically, rather than writing every detail by hand". He goes on to say that map and filter are two common examples of such combinators.
Some combinators which match the first definition:
S
K
Y
others from To Mock a Mockingbird (I may be wrong -- I haven't read this book)
Some combinators which match the second definition:
map
filter
fold/reduce (presumably)
any of >>=, compose, fmap ?????
I'm not interested in the first definition -- those would not help me to write a real program (+1 if you convince me I'm wrong). Please help me understand the second definition. I think map, filter, and reduce are useful: they allow me to program at a higher level -- fewer mistakes, shorter and clearer code. Here are some of my specific questions about combinators:
What are more examples of combinators such as map, filter?
What combinators do programming languages often implement?
How can combinators help me design a better API?
How do I design effective combinators?
What are combinators similar to in a non-functional language (say, Java), or what do these languages use in place of combinators?
Update
Thanks to #C. A. McCann, I now have a somewhat better understanding of combinators. But one question is still a sticking point for me:
What is the difference between a functional program written with, and one written without, heavy use of combinators?
I suspect the answer is that the combinator-heavy version is shorter, clearer, more general, but I would appreciate a more in-depth discussion, if possible.
I'm also looking for more examples and explanations of complex combinators (i.e. more complex than fold) in common programming languages.
I'm not interested in the first definition -- those would not help me to write a real program (+1 if you convince me I'm wrong). Please help me understand the second definition. I think map, filter, and reduce are useful: they allow me to program at a higher level -- fewer mistakes, shorter and clearer code.
The two definitions are basically the same thing. The first is based on the formal definition and the examples you give are primitive combinators--the smallest building blocks possible. They can help you to write a real program insofar as, with them, you can build more sophisticated combinators. Think of combinators like S and K as the machine language of a hypothetical "combinatory computer". Actual computers don't work that way, of course, so in practice you'll usually have higher-level operations implemented behind the scenes in other ways, but the conceptual foundation is still a useful tool for understanding the meaning of those higher-level operations.
The second definition you give is more informal and about using more sophisticated combinators, in the form of higher-order functions that combine other functions in various ways. Note that if the basic building blocks are the primitive combinators above, everything built from them is a higher-order function and a combinator as well. In a language where other primitives exist, however, you have a distinction between things that are or are not functions, in which case a combinator is typically defined as a function that manipulates other functions in a general way, rather than operating on any non-function things directly.
What are more examples of combinators such as map, filter?
Far too many to list! Both of those transform a function that describes behavior on a single value into a function that describes behavior on an entire collection. You can also have functions that transform only other functions, such as composing them end-to-end, or splitting and recombining arguments. You can have combinators that turn single-step operations into recursive operations that produce or consume collections. Or all kinds of other things, really.
What combinators do programming languages often implement?
That's going to vary quite a bit. There're relatively few completely generic combinators--mostly the primitive ones mentioned above--so in most cases combinators will have some awareness of any data structures being used (even if those data structures are built out of other combinators anyway), in which case there are typically a handful of "fully generic" combinators and then whatever various specialized forms someone decided to provide. There are a ridiculous number of cases where (suitably generalized versions of) map, fold, and unfold are enough to do almost everything you might want.
How can combinators help me design a better API?
Exactly as you said, by thinking in terms of high-level operations, and the way those interact, instead of low-level details.
Think about the popularity of "for each"-style loops over collections, which let you abstract over the details of enumerating a collection. These are just map/fold operations in most cases, and by making that a combinator (rather than built-in syntax) you can do things such as take two existing loops and directly combine them in multiple ways--nest one inside the other, do one after the other, and so on--by just applying a combinator, rather than juggling a whole bunch of code around.
How do I design effective combinators?
First, think about what operations make sense on whatever data your program uses. Then think about how those operations can be meaningfully combined in generic ways, as well as how operations can be broken down into smaller pieces that are connected back together. The main thing is to work with transformations and operations, not direct actions. When you have a function that just does some complicated bit of functionality in an opaque way and only spits out some sort of pre-digested result, there's not much you can do with that. Leave the final results to the code that uses the combinators--you want things that take you from point A to point B, not things that expect to be the beginning or end of a process.
What are combinators similar to in a non-functional language (say, Java), or what do these languages use in place of combinators?
Ahahahaha. Funny you should ask, because objects are really higher-order thingies in the first place--they have some data, but they also carry around a bunch of operations, and quite a lot of what constitutes good OOP design boils down to "objects should usually act like combinators, not data structures".
So probably the best answer here is that instead of combinator-like things, they use classes with lots of getter and setter methods or public fields, and logic that mostly consists of doing some opaque, predefined action.

CSS combinator precedence?

Is there a precedence to combinators like
a > b ~ c d
(Note the space between c and d is the descendant combinator)
Or is it just read left-to-right, like
((a > b) ~ c) d
?
No, there is no notion of precedence in combinators. However, there is a notion of order of elements in a complex selector.
Any complex selector can be read in any direction that makes sense to you, but this does not imply that combinators are distributive or commutative, as they indicate a relationship between two elements, e.g. ancestor descendant and previous + next. This is why the order of elements is what matters.
According to Google, however, browsers implement their selector engines such that they evaluate complex selectors from right to left:
The engine [Gecko] evaluates each rule from right to left, starting from the rightmost selector (called the "key") and moving through each selector until it finds a match or discards the rule.
Mozilla's article, Writing Efficient CSS for use in the Mozilla UI has a section that describes how their CSS engine evaluates selectors. This is XUL-specific, but the same layout engine is used both for Firefox's UI and pages that display in Firefox's viewport. (dead link)
As described by Google in the above quote, the key selector simply refers to the right-most simple selector sequence, so again it's from right to left:
The style system matches rules by starting with the key selector, then moving to the left (looking for any ancestors in the rule’s selector). As long as the selector’s subtree continues to check out, the style system continues moving to the left until it either matches the rule, or abandons because of a mismatch.
Bear in mind two things:
These are documented based on implementation details; at heart, a selector is a selector, and all it is intended to do is to match an element that satisfies a certain condition (laid out by the components of the selector). In which direction it is read is up to the implementation; as pointed out by another answer, the spec does not say anything about what order to evaluate a selector in or about combinator precedence.
Neither article implies that each simple selector is evaluated from left to right within its simple selector sequence (see this answer for why I believe this isn't the case). What the articles are saying is that a browser engine will evaluate the key selector sequence to figure out if its working DOM element matches it, then if it does, progress onto the next selector sequence by following the combinator and check for any elements that match that sequence, then rinse and repeat until either completion or failure.
With all that said, if you were to ask me to read selectors and describe what they select in plain English, I would read them from right to left too (not that I'm certain whether this is relevant to implementation details though!).
So, the selector:
a > b ~ c d
would mean:
Select any d element
that is a descendant of a c element
that is a sibling of, and comes after, a b element
that is a child (direct descendant) of an a element.
It doesn't matter.
a > b c
will match the same elements regardless of whether you do it
(a > b) c
or
a > (b c)
I think that browsers go right-to-left.
the spec doesn't mention anything about precedence (that I can find) but I believe it's strictly left -to- right evaluation

Difference between a procedure and a combinator?

I've been using Scheme and Common Lisp for a while and there is one thing about nomenclature that I never got:
I know that combinators are procedures with no free variables, but I seldom see them being called "combinators", except for those that deal with lists and other sequences.
Is my perception correct? Or is there some other definition of "combination" that I'm missing?
If you have any function that deals with lists, then it's no longer a real combinator, since it needs to use list functions. A "real" combinator is one that really uses no free identifiers, not even cons etc. (But the term can sometime be used more loosely.)

Resources