What is Expressiveness in a Computer Language

Pascal Bourguignon pjb at informatimago.com
Thu Jun 22 12:45:22 EDT 2006


Matthias Blume <find at my.address.elsewhere> writes:

> Pascal Bourguignon <pjb at informatimago.com> writes:
>
>> Moreover, a good proportion of the program and a good number of
>> algorithms don't even need to know the type of the objects they
>> manipulate.
>>
>> For example, sort doesn't need to know what type the objects it sorts
>> are.  It only needs to be given a function that is able to compare the
>> objects.
>
> Of course, some statically typed languages handle this sort of thing
> routinely.
>
>> Only a few "primitive" functions need specific types.
>
> Your sort function from above also has a specific type -- a type which
> represents the fact that the objects to be sorted must be acceptable
> input to the comparison function.

Well, not exactly.  sort is a higher level function. The type of its
arguments is an implicit parameter of the sort function.

     (sort "Hello World"  (function char<=))
     --> " HWdellloor"

     (sort '(52 12 42 37) (function <=))
     --> (12 37 42 52)

     (sort (list (make-instance 'person               :name "Pascal")
                 (make-instance 'unit                 :name "Pascal")
                 (make-instance 'programming-language :name "Pascal"))
           (lambda (a b) (string<= (class-name (class-of a))
                                   (class-name (class-of b)))))
     --> (#<PERSON #x205763FE>
          #<PROGRAMMING-LANGUAGE #x205765BE>
          #<UNIT #x205764DE>)


In Common Lisp, sort is specified to take a parameter of type SEQUENCE
= (or vector list), and if a list it should be a proper list,
and a function taking two arguments (of any type) 
and returning a generalized boolean (that is anything can be returned,
NIL is false, something else is true)


So you could say that:

   (sort (sequence element-type)
         (function (element-type element-type) boolean))
    --> (sequence element-type)

but element-type is not a direct parameter of sort, and can change for
all calls event at the same call point:

(mapcar (lambda (s) (sort s (lambda (a b) (<= (sxhash a) (sxhash b)))))
        (list (vector 52 12 42 37)
              (list   52 12 42 37)
              (list "abc" 'def (make-instance 'person :name "Zorro") 76)))
--> (#(12 37 42 52)
      (12 37 42 52)
      (76 #<PERSON #x2058D496> DEF "abc"))


>> So basically, you've got a big black box of applicaition code in the
>> middle that doesn't care what type of value they get, and you've got a
>> few input values of a specific type, a few processing functions
>> needing a specific type and returning a specific type, and a few
>> output values that are expected to be of a specific type.  At anytime,
>> you may change the type of the input values, and ensure that the
>> needed processing functions will be able to handle this new input
>> type, and the output gets mapped to the expected type.
>
> ...or you type-check your "black box" and make sure that no matter how
> you will ever change the type of the inputs (in accordance with the
> interface type of the box) you get a valid program.

When?  At run-time?  All the modifications I spoke of can be done at
run-time in Lisp.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The mighty hunter
Returns with gifts of plump birds,
Your foot just squashed one.



More information about the Python-list mailing list