Skip to content

zzz notes: OO methods, type classes, etc

David Jeske edited this page May 9, 2017 · 10 revisions

Runtime Polymorphism over Hetrogenous Collections

This is the cornerstone of OO style programming, whether Python dynamic Duck Typing, or C++/Java Class/Interface programming.

For this to scale reasonably, we need a method-table per-class, not per instance.

BROKEN simple existential type iteration

(include "lib/basis.scm")


; simple flat list
; (for-each (lambda (x) (printf (int x) " ")) (LIST 1 2 3 4))


; row polymorphic list

(define (foo x) ;; : ({c=int ...} -> #u)
   (begin
    (printf (int x.c) " ")
     #u
    ))

(define a_list : (list {c=int ...})
    (LIST {a=1 b=2 c=3} {c=4})) ;; we want a list of {c=int ...}


;; neither of these lines will pass the typecheker

(for-each (lambda (x) (printf (int x.c) " ")) a_list)
; (for-each foo                                 a_list)

;; should print --> 3 4
0

;; instead it's a compiler error...

ubuntu@ip-172-30-1-159:~/irken-test$ irken exten_typing.scm
read...
transform...
user type in expression: (list {c=int ...})
opt1...
opt2...
depgraph...
typing...
  5968    3  100         primapp %rextend c : {c=int }
  5966    1  100           primapp %rmake #f : {}
  5967    1  100           literal 3 : int
  5969    1  100         literal 2 : int
  5971    1  100       literal 1 : int
  5976    3  100     primapp %rextend c : {c=int }
  5974    1  100       primapp %rmake #f : {}
  5975    1  100       literal 4 : int
  6441    1  100     primapp %dtcon list:nil : (list {c=int })
  6435    3  100     primapp %dtcon list:cons : (list {c=int })
  6438    1  100       varref arg0_18_i28 : {c=int }
  6439    1  100       varref arg1_19_i29 : (list {c=int })
  6429    3  100     primapp %dtcon list:cons : ?
  6432    1  100       varref arg0_18_i26 : {c=int }
  6433    1  100       varref arg1_19_i27 : (list {c=int })
  6017   24 1000   sequence : ?
  6442   38          let (v_701_i76) : ?
  6443    1  100       cexp (vector symbol) (object *) pxll_internal_symbols : ?
  6444   34            sequence : ?
  6445    3  100         varset the-symbol-table_253 : ?
  6446    1  100           primapp %dtcon tree:empty : ?
  6447   30              let ($n0_702_i76) : ?
  6448    2  100           cexp ((vector t10) -> int) (%0 == (object*) TC_EMPTY_VECTOR) ? 0 : GET_TUPLE_LENGTH(*%0) : ?
  6449    1  100             varref v_701_i76 : ?
  6450   25                fix ($loop1_703_i76)  : ?
  6451   20                  function $loop1_703_i76 (i_704_i76)  : ?
  6452   18 1000               conditional : ?
  6453    3  100                 cexp (int int -> bool) %0==%1 : ?
  6454    1  100                   varref i_704_i76 : ?
  6455    1  100                   varref $n0_702_i76 : ?
node id=6433

Type Error:
        abs
        (pre int)

***
Runtime Error, halting: "type error"
-1

WORKING, but method-table per instance

;; implement the polymorphic shapes example from
;; https://wiki.haskell.org/Existential_type

(include "lib/basis.scm")

(define pi 3)

;; define a type class "add"
(typealias typeclass/shape {
   perimeter=(-> int)
   area=(-> int)
 })


;; define an instance of typeclass shape for circle
(define (Circle r) : (int -> typeclass/shape)
   (let ((this {radius=r}))
   (define perimeter -> (* 2 (* pi this.radius)))
   (define area -> (* pi (* this.radius this.radius)))
   { perimeter=perimeter area=area }
   )
)

;; define an instance of typeclass shape for rectangle
(define (Rect w h) : (int int -> typeclass/shape)
   (let ((this {width=w height=h}))
   (define perimeter -> (* 2 (+ this.width this.height)))
   (define area -> (* this.width this.height))
   { perimeter=perimeter area=area }
   )
)

(define c (Circle 2))
(define r (Rect 2 2))

;; perform operations using add
(printf (int   (c.area)) "\n")
(printf (int   (r.area)) "\n")

(define objects  (LIST  (Circle 3) (Rect 3 3) ))

(map (lambda (x) (printf (int (x.area)) "\n")) objects)

Eventually The OO methods should have features like:

  • function argument type overloading - like Type Classes, name-mangled overloading, etc.
  • add method implementations to existing objects - like Obj-C Categories
  • static dispatch and inlining when possible - like Type Classes, non-virtual methods
  • dynamic dispatch / vtable when necessary - like Existential Types, virtual methods

Notes about Ocaml

Clone this wiki locally