kleopatra999 / owl-lisp

Automatically exported from code.google.com/p/owl-lisp
2 stars 1 forks source link

Finite functions should be functions #55

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
It should be possible to invoke finite functions as functions:

(define foo (list->ff '((bananas . 1) (apples . 2) (oranges . 3))))
(foo 'bananas 0) => 1
(foo 'grapes 0) => 0

Original issue reported on code.google.com by johnwco...@gmail.com on 18 Dec 2011 at 6:44

GoogleCodeExporter commented 9 years ago
Do not tempt me :) It took *lots* of self restraint not to do this, along with 
a few other additions which for some extra semantic complexity would give cool 
language features. I'll try to continue not adding this feature.

Original comment by aohelin on 19 Dec 2011 at 8:29

GoogleCodeExporter commented 9 years ago
I may not be able to offer you the kingdoms of the earth, but I *will* argue 
that this is the Right Thing.  In a pure lambda calculus world, the only thing 
that matters is a function behaves, not how it is defined.  These finite 
functions are just as much functions as lambda-defined functions are: they 
simply allow other functions to be constructed from them (as a benefit of how 
simple they are), whereas lambda-defined functions are fully opaque.

It's true that you could write a wrapper-unwrapper for finite functions like 
this:

(define *wrap-magic* (cons False False))
(define (wrap-ff ff) (lambda (key default)
  (if (eq? key *wrap-magic*) ff (get ff key default))))
(define (unwrap-ff f) (f *wrap-magic* False))

But it's messy having to switch back and forth between the procedure and the 
finite function all the time or keep around two variables where logically one 
would suffice.  Much cleaner to have finite functions be procedures that happen 
to have a different representation.

Original comment by johnwco...@gmail.com on 19 Dec 2011 at 10:54

GoogleCodeExporter commented 9 years ago
This is what happens when you put function to the name of a data structure :)

These could have been called hashes, dicts or key-value trees, but they all 
suggest a particular underlying data structure or comparson, or maps, which 
might cause confusion with other standard functions. Finite functions are a 
suitable concept from maths, but here the name suggests a library-defined data 
structure implementing them, not a programming language construct that is one.

As you said the difference is in opaqueness. The underlying data structure has 
to be something other functions can access the components of in order to be 
able to implement folds, deletion, insertion and other necessary operations. 
The LC-counterpart would be something like λxlkvr.(x l k v r), assuming 
emptiness, color and compaction were ignored. The current situation is that due 
to their importance the VM does provide some support handling them, namely 
filling in left and right branches and omitting them during construction to 
reduce memory load of large ffs, but they haven't been made callable.

Still, putting back to to-think queue.

Original comment by aohelin on 19 Dec 2011 at 11:30

GoogleCodeExporter commented 9 years ago

Original comment by aohelin on 19 Dec 2011 at 2:03

GoogleCodeExporter commented 9 years ago
Added due to frequent public whining :P

> (define ff (list->ff '((apple . orange) (lemon . grapefruit) (orange . 
lemon))))
ff
> (ff (ff 'apple 'missing) 'missing)
lemon
>

They are not functions as in function?, but are callable.

Original comment by aohelin on 23 Dec 2011 at 9:28