A Function-oriented Dialect of JavaScript

- Papuascript
- Function-oriented programming
- Why not Object-oriented?
- Type classes for JavaScript / Papuascript
- Customized function chaining

Functionality forms a Venn diagram, not a tree. Some data can be ordered, but not added (surnames can be ordered lexicographically, but adding them has no meaning); some data can be added, but not ordered (arrays containing mixed data can be concatenated, but ordering them would make no sense); and some data can be both added and ordered (numbers).

Here's a diagram of some types in Haskell:

Enum, Ord, Num, Integral, and Fractional are all
type classes. Data types
that are instances of Enum have a discrete set of possible values; Ord's can be
compared using `<`

and `>`

; Num's can be added,
subtracted and multiplied; Integral types supports `mod`

and
dividing with remainders; and Fractional types support division. If you can
work out a classical inheritance tree from this diagram, your kung fu is
better than mine.

OO languages have interfaces, but they require you to
re-implement the methods of the interface for every class. Some
OO languages have features that allow you to emulate the true
Venn-diagram nature of data - Ruby has "modules," for example -
but these tend to be incomplete or complicated or both, and, in
any case, why base your language around inheritance in the first
place? Overlapping, non-hierarchical relationships are the
*norm*, not the exception.

Here is a simple emulation of Haskell-style type classes. Without Haskell's type system, our type classes will not have nearly the powerful they would have in that language, but they still provide a credible alternative to inheritance-based models.

```
typeClass defaultDefs typeClassFuncs methods =
/* function that adds type class functionality to a constructor
*
* constr$: type (constructor function) to be modified
* classFuncs: type-specific definitions and overrides
* for functions in this type class
*/
typeKlass = \constr$ typeFuncs ->
// set type functions by passing type to genDefault
for k:genDefault in defaultDefs
constr$[k] := typeFuncs[k] || genDefault constr$
// set methods by passing type's function to memberFunc
for k:genMethod in methods
constr$.prototype[k] := genMethod constr$[k]
// add generic functions to type class object
for kk:vv in typeClassFuncs
typeKlass[kk] = typeClassFuncs[kk]
typeKlass
```

As an example, we create the simple type class `Show`

, for
converting objects to strings.

```
// define type class Show
Show = typeClass
// generates default implementation for a given type
{ show: \type -> \a -> a.toString()
, showList: \type -> \xs -> fmap type.show xs .join ','
}
// these will become Show.show and Show.showList
{ show: \a -> a.show()
, showList: \xs -> xs.0.constructor.showList xs
}
// generates methods from type-level function
{ show: \f -> \ -> f this
}
```

And now we make RegExp an instance of Show; i.e., we add the functionality of Show to RegExp.

```
// make RegExp an instance of Show
Show RegExp
{ show: \regex -> regex.source
, showList: \xs -> '/' + fmap RegExp.show xs .join '/, /' + '/'
}
// now show and showList can be used with RegExp objects
console.log # /a*b*/.show()
console.log # Show.showList [/abc/, /def/]
```

Another example of a type class is `Eq`

, which defines equality.
Note that the default implementations of `is`

and `isnt`

call
each other. Types implementing `Eq`

must override at least one of
these defaults, or calling either will result in an infinite
loop!

```
// type class for things which can be equal or unequal
Eq = typeClass
{ is: \type -> \a b -> !(type.isnt a b)
, isnt: \type -> \a b -> !(type.is a b)
}
{ is: \a b -> a.is b
, isnt: \a b -> a.isnt b
}
{ is: \f -> f this @
, isnt: \f -> f this @
}
Eq RegExp
{ is: \a b -> a.source == b.source
}
console.log # /abc/ .is /abc/
console.log # /abc/ .isnt /def/
```

Project maintained by Rob Rosenbaum Theme by mattgraham, modified by Rob Rosenbaum