2014-07-20

Functions in speech

Functional programming languages, and also modern imperative/multi-paradigm programming languages, often allow us to use functions without declaring it remotely. These are either called “anonymous functions” or “lambda expressions”. The only difference is that anonymous functions tend to be made of statements (see JavaScript), whereas lambda expressions contain, um, an expression (see Haskell). There is a third way (as seen in J and stack-based languages) in which anonymous functions are constructed using combinators. This is also seen in Haskell-like languages, in which it is called “points-free style”.

In a spoken language, the idea of side effects doesn't really apply. Hence, we don't need anonymous functions made up of statements. What look like statements in spoken languages can be seen as expressions that return a boolean value (true, hopefully). Other values can be derived by describing them in terms of predicates they satisfy. So we just need to find a way to create boolean-yielding functions.

Fortunately, our languages are full of boolean-yielding functions. We call them “selbri” or “verbs”. But we need more. In Lojban, there are 4 basic ways to make new selbri from old ones: tanru, lujvo, {be} phrases and abstractions. For my language, I consider tanru grammatically identical to {be} phrases, with some tags of the two component selbri linked together in normal tag clusters. There is no need for a word {be}, since links between selbri are always made explicitly.

That just leaves lujvo and abstractions. I'll start with abstractions. Lojban abstractions do a variety of things:
  • {du'u} refers to the fact of whether the contained bridi is true.
  • {nu} refers to events at which the contained bridi is true.
  • {ka} makes a function that takes a sumti as a parameter and describes how that sumti fits with the rest of the contained bridi.
  • {ni} refers to the extent to which the contained bridi is true, presumably as a number between 0 and 1.
There are some others, too. Of those, {ka} is the one that stands out. The rest just need a bridi, but {ka} needs a bridi containing 1 or more {ce'u}s, where {ce'u} is a cmavo confusingly glossed as “lambda”.

Property abstractions in my language are fairly similar to Lojban's {ka} abstractions, but aren't necessarily bound to a contiguous place in the sentence (though that does usually make things easier). 〈ka〉 is like any other selbri, but has a tag 〈ce'u〉 described as the “test set”. I call it this because 〈ka fa〉 acts like a function that tests its argument for membership in the set specified at 〈ce'u〉.

That's all we need, so here are the obligatory jumping dogs. I'll use the Lojban word {kakne} – “fa can do fe”. (I drop “under conditions x3” because any single dog is in exactly 1 condition. This follows from what I said about tenses. Noöne uses that place, anyway.) The result is 〈gerku fafa kakne fefa ka ce'ufa plipe〉, meaning “at least 1 dog can leap”.

{ka} is also used in Lojban to make functions with more arguments. This is done by adding more {ce'u}s, where the order of occurrences of the {ce'u}s determines which argument they get (alternatively, it's possible to name them in a {ce'ai} prenex to give them a different order). In my language, using a place again just adds to the claims of what's in that set. Because sets are unordered, this can't create ordered parameters. I could add more 〈ce'u〉-like places, but I don't have the vocabulary for that right now. Instead, I'll introduce a syntactic alternative which works well for binary functions.

As I said earlier, my language doesn't have tanru, so I can repurpose {ke} and {ke'e}. I'll use these for “function brackets”. Any tags immediately to the right of 〈ke〉 is connected to the first parameter, and any tags immediately to the left of 〈ke'e〉 are connected to the second parameter. A special rule says that both tags refer inwards by default. From the outside, the whole expression is grammatically atomic, and behaves like a brivla. 〈ke ... ke'e fa〉 is the test function on two arguments.

Examples of binary {ka} in Lojban are difficult to find. One I can think of is the x2 place of {porsi}. Let 〈porsi〉 have the definition “list fa is sorted by comparison fe from set fi”. 〈porsi fe〉 is then a function like “<”, which would be used to sort numbers into ascending order. To avoid introducing too much grammar, I'll stick to sorting a set of numbers. I do, though, have to introduce some grammar to deal with constructing lists and sets. In short, constructors are contained within a 〈vei〉...〈ve'o〉 pair. 〈vei〉 is followed by a selbri specifying the type of connection, then each item is specified by 〈ju'e〉s in order, with tags connected to each (tags adjacent to a 〈ju'e〉 refer away from it, by default). The last element's tag can connect to 〈ve'o〉, or the identity element can be taken from the selbri.

Sets use the selbri 〈ce〉 (“fa is the set made of element fe connected to set fi”), and lists use 〈ce'o〉 (“fa is the list made by appending element fe to the left of list fi”, or, in Haskell “fa = fe:fi”). The pattern also allows other monoids, and even non-monoids, to have similar constructors, but I digress. We now have enough for my planned example: 〈vei ce 2 faju'e 7 faju'e 4 faju'e 3 fave'o fafi porsi fefa kefa mleca feke'e ) fifa vei ce'o 2 faju'e 3 faju'e 4 faju'e 7 fave'o〉. In real speech, the 〈ke〉...〈ke'e〉 structure would be redundant; we'd extract a function directly from 〈mleca〉 (“fa < fe”). But if we had a more complex relationship to satisfy, the function brackets would become necessary.

After that example, I really want to describe quicksort! We need some more grammar and vocabulary, though.

No comments:

Post a Comment