RSS Feed

Lisp Project of the Day

simplified-types

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

simplified-typeslanguagetyping

Documentation😀
Docstrings🥺
Tests 🥺
Examples😀
RepositoryActivity🥺
CI 🥺

Yesterday I wrote a simple implementation of dataframe. A dataframe stores data columns as simple vectors of some type.

For this implementation, I needed a type inference to set vector's type for each column. An inferred type should be generic enough to work for all items in the column.

But what if we have positive and negative integers in our data? What type will return the standard type-of?

Here is the answer:

POFTHEDAY> (type-of 21)
(INTEGER 0 4611686018427387903)

POFTHEDAY> (type-of -21)
FIXNUM

So, if I'll make my vector's type (INTEGER 0 4611686018427387903) it will raise an error on the second element:

POFTHEDAY> (make-array
            2
            :element-type '(INTEGER
                            0
                            4611686018427387903)
            :initial-contents '(21 -21))
; Debugger entered on
; #<TYPE-ERROR expected-type:
; (UNSIGNED-BYTE 62) datum: -21>

That's why I started to search the way to make inferred type more generic and found simplified-types library.

Here is how it works:

POFTHEDAY> (mapcar #'type-of
             '(21 -23 1.23 4.56d0 "string"))

((INTEGER 0 4611686018427387903)
  FIXNUM
  SINGLE-FLOAT
  DOUBLE-FLOAT
  (SIMPLE-ARRAY CHARACTER (6)))
    
POFTHEDAY> (mapcar #'simplified-types:simplified-type-of
             '(21 -23 1.23 4.56d0 "string"))

((INTEGER 21 21)
 (INTEGER -23 -23)
  SINGLE-FLOAT
  DOUBLE-FLOAT
  T)

However, INTEGER with bounds still is not what I need for my application. Happily, Marco Heisig foresee this need and added a switcher which makes integer types more generic.

With this option, the library produces exactly what I need:

POFTHEDAY> (let ((simplified-types::*precise-integer-types* nil))
             (mapcar #'simplified-types:simplified-type-of
               '(21 -23 1.23 4.56d0 "string")))

((INTEGER * *)
 (INTEGER * *)
  SINGLE-FLOAT
  DOUBLE-FLOAT
  T)

If you'd like to work with types in Common Lisp, then you probably might be interested in the library I've reviewed recently - trivialib.type-unify. It allows us to do pattern-matching on type specifiers.


Brought to you by 40Ants under Creative Commons License