arrayscommon-lisptype-systemsclozure-cl

In Common Lisp (ClozureCL), what expression yields a value of type `(SIMPLE-ARRAY ARRAY (5 3 *))`?


I am trying to learn CL using ClozureCL and am in the middle of Google's Lisp koans.

Spoiler warning: I'm giving away an answer to frame my question, because if I don't do so, submitted answers might not be as targeted.


The code here shows a value of x that passes.

(define-test test-guess-that-type!
  (let ((x '(SIMPLE-ARRAY ARRAY (5 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
    (assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x))
    (assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))

I didn't feel like I learned much though beyond the pattern used in type notation. I wanted to see if I can pass the test using a value of x in the form (type-of ...) so that I can relate actual values to types by example.

That said, here's my current uneducated guess. The assert I marked with ; <!> is failing for my first chosen value for x.

(define-test test-guess-that-type!
  (let ((x (type-of (make-array '(5 3 33) :element-type 'VECTOR))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (* 3 *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY T (5 * *))))
    (assert-true (subtypep x '(SIMPLE-ARRAY ARRAY *)))
    (assert-true (typep (make-array '(5 3 9) :element-type 'STRING ) x)) ; <!>
    (assert-true (typep (make-array '(5 3 33) :element-type 'VECTOR ) x))))

My question is: If you are restricted to use of (type-of <val>) what <val> solves the koan?

Observations thus far:


Solution

  • I don't think there's a solution to this. Actually, it's possible that you might find a solution in some CL implementations, but there's no guarantee about it. The specification of TYPE-OF doesn't go into detail about the type specifier returned in most cases, merely requiring that

    (typep object (type-of object))
    

    must be true, along with a few other retrictions. But there's nothing specific to arrays.

    I don't think any implementations will ever return type specifiers containing * in the dimensions for an array type. They'll likely either return a very general type specifier that omits the dimensions entirely, or a very specific one that contains the actual dimensions of the given array.

    Nothing prevents an implementation from returning a type specifier like the one you're looking for, but it would be pretty perverse. Given a 3-dimensional array, why would it specifically choose to make the last dimension unspecified rather than one or all of the others?