== Fundamental Features ==
fuphyl is still in an experimental state, so the implementation details and syntax specifics are still up for debate. However, the project was founded with a few properties in mind that will not be changed.
The following is the list of fundamental features for fuphyl:
* No destructive updates or explicit memory management but no garbage collection
* Strong typing but with most types deducible
* All scalars are 1-tuples and all 1-tuples of N-tuples are N-tuples
* A function call is just the juxtaposition of a function name and a tuple
* A procedural-inspired syntax
* OO syntax is just syntactic sugar
=== No destructive updates or explicit memory management ===
A lack of destructive updates simplifies the syntax and the compiler logic. As a bonus, it makes it totally impossible to get reference cycles between objects, so all memory management can be done by reference-counting, which is deterministic, unlike GC. Having a reference count for objects also means that certain operations can check the reference count on the object and be implemented destructively since it is known whether or not there exists any way of seeing the modifications. As an optimization, this does not prevent small, non-nillable objects from being allocated on the stack and copied instead of being reference-counted on the heap, which is quite wasteful for a small, cheap object such as an int.
This intentionally leaves open the possibility of impure functions, message passing, and exceptions.
=== Strong typing but with most types deducible ===
Static typing means that overloading functions is possible and that many more errors can be caught at compile-time than in a dynamic-typed language. Explicitly specifying types all the time can be annoying; however, without destructive updates there is no reason to define a variable without giving it a value, so variables can have their type deduced (at compile-time) by the return type of the initialising expression. Of course, explicitly specifying types will always be possible.
The feature name intentionally uses the vague word "strong" instead of static, because the intent is not to prohibit limited dynamic typing. Both variant and polymorphic types are both in the plan.
=== All scalars are 1-tuples and all 1-tuples of N-tuples are N-tuples ===
To clarify, that means that
5 <=> (5)
( (1,2,3) ) <=> (1,2,3)
( (5) ) <=> (5)
As a consequence, precedence-overriding parentheses need not be included, since the tuple creation sysntax has the same effect.
As an example:
( 1 + 2 ) * 3
( (1) + (2) ) * (3) // scalar is 1-tuple
( (3) ) * (3) // result of the addition
(3) * (3) // 1-tuple of N-tuple is the enclosed N-tuple
(9) // result of the multiplication
=== A function call is just the juxtaposition of a function name and a tuple ===
This appears to be a rather academic point to make, but it turns out to allow some interesting constructions.
Suppose you have a length function that can be called as follows:
len = length( 1, 2, 3 );
Because it's simply the tuple adjacent to the function name, the following is also valid:
vec = (1,2,3);
len = length vec;
Using the 1-tuple rule above, this is equivalent to the following, more C-styled syntax:
vec = (1,2,3);
len = length(vec);
So this means that the parentheses used in C-style function call systax needn't be a special case either.
=== A procedural-inspired syntax ===
Many functional languages have quite elegant syntax. LISP's S-expressions allow macros; others manage to keep the whole thing a mathematically-pure expression. For better or worse, however, many programmers seem to be more comfortable with procedural-style systax.
This is not to say that fuphyl has to or will be another language copying C's syntax. The lack of destructive updates makes numerous changes essential. For example, there are no loops and if/elif/else will return a value.
Various popular languages (C++, Java) have manged to do object-oriented programming in a procedural syntax, so it should work fine in fuphyl as well.
=== OO syntax is just syntactic sugar ===
Member functions in most languages can be understood as non-member functions with an implicit this or self parameter. fuphyl takes this and uses it to challenge the Java notion of object orientation. Instead of making all functions be member functions, no functions are member functions but any function could be used as a member function.
For example, any time
a.b(c,d)
is encountered, it is always equivalent to
b(a,c,d)
As a bonus, this means that there is no need for a class definition syntax. "class"es are simply tuples for which function call lookup is delayed until runtime to use the runtime type.
Does this mean that fuphyl "isn't object-oriented"? I'd say no. If fact, one could say it's more object-oriented than many other "OO" languages, if you choose to write in an OO style.
Jonathan Rees has put together an interesting list of features that various people have decided are "OO": http://www.paulgraham.com/reesoo.html , which are a good way to attempt to answer the question.
* Encapsulation
If anything, this approach could be seen as being more encapsulated. There is no longer a need to know whether a function is defined inside a class or outside, all functions can be used either way, whichever is clearest at the time. Additionally there's no need for a special syntax for member function pointers.
* Protection
Instead of using the class definition to define the limits of access to the implementation of a polymorphic type, a different system can be used. Since people tend to put one class per file (and fuphyl will not be using the proprocessor-includes compilation model) the file is a convenient border. As a bonus, classes defined in the same file, which are presumably tightly coupled, will have access to the implementation of the other classes to which it is tightly coupled, reducing the need to make internals public in the interest of intuitive class organization.
* Ad hoc polymorphism
Functions and types will be able to be defined over arbitrary types, not unlike templates in C++, though hopefully with more intuitive and less ambiguous syntax.
* Parametric polymorphism
I personally don't believe that a list of absoluely anything is all that useful. fuphyl will, however, allow lists of variants or polymorphic types which are more typesafe.
* Everything is an object
The question here would become "what is an object"? That being said, in fuphyl everything is a tuple and everything can use object syntax.
* All you can do is send a message
This fits easily. With no destructive operations, the only way to "modify" a variable is to call a function on it that will return a new one.
* Specification inheritance
Polymorphic types will implement Liskov-style inheritance.
( See http://en.wikipedia.org/wiki/Liskov_substitution_principle and http://www.objectmentor.com/resources/articles/lsp.pdf for details about the Liskov Substitution Principle )
* Implementation inheritance/reuse
Higher-order functions do this easily. Additionally, if overload resolution involving polymorphic types cannot find a perfect match, it will attempt to find matches as though the polymorphic type were an instance of one of its base classes, so functions need not be reimplemented if the base's implementation is acceptable.
* Sum-of-product-of-function pattern
I dont' see why this is an advantage. Certainly it makes multipule dispatch quite complicated, when a more general system can handle it quite gracefully.