Skip to content

Alternative defunctionalisation technique #581

Open
@hummy123

Description

@hummy123

Hi there,

I was implementing a trie/prefix tree data structure (here) and, while considering how to implement fold on the data structure, I think I noticed a conceptually simple defunctionalisation technique that doesn't require runtime dispatching on a datatype.

The kind of transformation I have in mind would turn the higher-order function Vector.foldl (for example) from:

Vector.foldl (fn (elt, acc) => elt + acc)

to:

signature VECTOR_FOLDL =
sig
  type vectorElementType 
  type environment
  type accumulator
  val folder : vectorElementType * environment * accumulator -> accumulator 
end

functor MakeVectorFoldl (Fn : VECTOR_FOLDL) =
struct
  fun helpFoldl (pos, env, acc, vec) =
    if pos = Vector.length vec
    then acc
    else
      let
        val elt = Vector.sub (vec, pos)
        val acc = Fn.folder (elt, env, acc)
      in
        helpFoldl (pos + 1, env, acc, vec)
      end

  fun foldl (env, initial, vec) = helpFoldl (0, env, initial, vec)
end

structure PlusFolder =
struct
  type vectorElementType = int
  type environment= unit
  type accumulator = int
  fun folder (elt, _, acc) = elt + acc
end

structure PlusVectorFoldl = MakeVectorFoldl (PlusFolder)

(* higher order function which I think will not have a runtime dispatch cost *)
val foldl = PlusVector.foldl 

so that MLton's defunctoriser in the elaborate pass doesn't need to construct a sun type over every higher order function and dispatch to the appropriate function at runtime.

I would like to have a go at implementing this kind of optimisation in MLton myself, but I might give up considering my total inexperience with coding compilers 😅 so I thought it wouldn't be bad to post it here in the event I get frustrated and fail, and there is interest from others in implementing the idea.

The transformation looks general to me (can mutate values in the environment record if user wants) and doesn't seem to require anything fundamentally novel to implement, but I would be interested in hearing criticism if it's not possible too.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions