Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ponylang - I can't figure out how to convert type

Tags:

ponylang

Starting with the helloworld, I am trying to learn me some pony by making an app which echoes back to the user what they have typed in. This works, except for the one line where I _env.out.print(_buffer).

class MyInput iso is StdinNotify
  var _env: Env
  var _buffer: Array[U8]

  new iso create(env: Env) =>
    _env = env
    _buffer = Array[U8].create()

  fun ref apply(data: Array[U8] iso) =>
    for item in (consume data).values() do
      if item == 0x0A then
        _env.out.print(_buffer)
        _buffer = Array[U8].create()
      end
      _buffer.push(item)
    end

The compile errors I get are:

argument not a subtype of parameter
        _env.out.print(_buffer)
                       ^
parameter type: ByteSeq val
  be print(data: ByteSeq) =>
           ^
argument type: Array[U8 val] ref
        _env.out.print(_buffer)   

From reading the source in github I think that Array[U8] should qualify as a ByteSeq, so I guess that it's a problem with the capabilities. I've tried a few things but I can't seem to copy my ref Array into a val Array. The closest I got was let out: Array[U8] box = _buffer

like image 446
Jonny Cundall Avatar asked Oct 18 '22 14:10

Jonny Cundall


1 Answers

thanks to the pony mailing list and more trial and error I've got it to work. (thanks sean allen)

actor Main
  new create(env: Env) =>
    env.out.print("welcome to the echo chamber")

    var input = recover iso MyInput.create(env) end
    env.input(consume input)

class MyInput is StdinNotify
  var _env: Env
  var _buffer: Array[U8] iso

  new  create(env: Env) =>
    _env = env
    _buffer = recover iso Array[U8].create() end

  fun ref apply(data: Array[U8] iso) =>
      for item in (consume data).values() do
        if  item == 0x0A then
          let bufferOutIso = _buffer = recover iso Array[U8].create() end
          _env.out.print(consume bufferOutIso)
        else
          _buffer.push(item)
        end
      end

so in case any of this needs explaining,

  • it turns out that although print asks for a val argument, it will take an iso, for reasons I don't fully understand
  • when using iso, you need to understand recover blocks and destructive read
  • I made a mistake putting iso in the class definition, I only needed to create the instance in a recover iso block
like image 151
Jonny Cundall Avatar answered Oct 21 '22 21:10

Jonny Cundall