Skip to content

ffi array type interop with opaque types #64

@joprice

Description

@joprice

I was trying to return an array from a function and use it with common Foldable and Traversable functions, and hit a wall of silent failures. Luckily, since the build doesn't detect changes in the output directory, I was able to throw some printlns in there and rebuild without it being overwritten. I found that casts in functions like Data.Array.length like

 xs, _ := xs_.([]Any)

return an empty array when the cast to interface fails.

To fix this, the type cannot simply be assigned to interface:

cannot use files (variable of type []os.FileInfo) as []interface{} value in variable declaration

so it needs to be copied, as this go wiki page points out:

https://github.com/golang/go/wiki/InterfaceSlice#what-can-i-do-instead

I'm wondering whether there's any way to get around this. Maybe define Traversable instances for an opaque type? I haven't tried this and not sure how much boilerplate it would require, but if there is some boilerplate on the go ffi side, maybe it could be provided in the small runtime library where Fn1-10 reside.

Below is the ffi function I ended up with that copies the array:

exports["readDir'"] = func(left Any) Any {
      return func(right Any) Any {
        return func(file_ Any) Any {
          file := file_.(string)
          return func() Any {
            files, err := ioutil.ReadDir(file)
            if err == nil {
              var f []interface{} = make([]interface{}, len(files))
              for i, d := range files {
                f[i] = d
              }
              return Apply(right, f)
            } else {
              return Apply(left, err.Error())
            }
          }
        }
      }
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions