Serguey,

A reasonable question, to which you might receive several possible answers:

At the risk of duplication, or just being a bit out of date now --- the previous go having failed as I needed to re-align my subscription address to my new coordinates --- let me add the following observations below.

Thanks for your continuing interest, and I hope this helps, (and perhaps my other colleagues will leap in to correct or contradict me!)

James McKinna
Radboud University Nijmegen

Serguey Zefirov wrote:
I hardly can find any example of higher-order functions in Epigram
examples. I searched distribution examples and online examples.

Why is that?
0) on the language and its library of examples
0a) the library, such as it is, has been focused on examples which show off the use of indices in type families to constrain computation: typically, these take the form of first-order data (lengths of vectors, size bounds on trees, type names...) used for measurement

0b) incidentally, the use of 'by' notation hides a lot of behind-the-scenes dependently-typed higher-order functions... actually, I don't think this is (co-)incidental at all --- see 3) below

1) on higher-order functions proper
1a) standard higher-order functions such as map, fold on lists etc. are all trivially available (and/but simply-typed!), so not much attention has been paid to them; functions which take dependently-typed functions as arguments are less common in nature or experience --- we are still learning to program this way. But you could try writing the version of "map" which takes a list of elements of A, a function f of type (x:A)B(x) which ensures each a in A is mapped to ... something satisfying property B, and returns a function mapping lists of As to lists of "elementwise B(-)s". If you were to try this example, it might throw up some interesting problems: should the result type be List (Sigma a:A. B[a]) or something more interesting? And then how do you write the function? Choices, choices, ...

1b) [Wouter's suggestion also includes this example] for a non-trivial example of a dt higher-order function, look at Conor's draft paper on closure under substitution in syntax with binders (I can probably supply a URL if you need it); we need more examples like this: in this case, the proofs were done years ago (by myself and Healf Goguen), and the programs re-invented in a slightly different way, only years later...

2) on a syntactic restriction
Epigram 1's syntax for let declarations and their bodies discourages writing functions which return functions ... e.g. Epigram 1 doesn't allow terms of the form lam x => case x { ...} for example: case x is an elimination operator, so is expected to appear in a <= expression. Taking functional arguments is no problem, though, and they can even be declared inference-rule style...

3) more speculatively, more abstractly
You might wonder about higher-order functions in the special case of parametric polymorphism in simply-typed languages: do they impose a uniformity on their use/application (or the use of their h-o arguments) which runs counter to the 'learning-by-testing' which arises in dependently-typed case analysis? What are the right ways to capture new kinds of such uniformities in the dependently-typed case? Again, only examples and experience will tell us. Here example 1b above is a good such candidate (sorry for the pun): h-o functions which carry around functional arguments representing abstract closure conditions on the intended source and target data. Elimination operators (0b above) are just one very general vision of that idea: for 'methods' in elimination operators are just 'abstract closure conditions which correspond to/arise from patterns of data' (typically, but not necessarily, given by constructor patterns).





Reply via email to