On Mar 6, 2006, at 4:08, Leopold Toetsch wrote:
Some remarks re the pdd and discussion so far.
o "write" ... [Is this redundant?]
"write" isn't needed. It is there, as some time ago, "print" was't
able to write strings with "\0"s inside.
Now marked in the PDD as deprecated.
(To make it easier to track changes, I added the PDD to the parrot
repository under docs/pdds/clip/, where the other non-finished PDDs
live.)
o "readline" ... Lines are truncated at 64K.
This limitation is history already.
I've updated src/ops/io.ops with this information.
* opcode vs function / method
open P0, "data.txt", ">"
print P0, "sample data\n"
Using opcodes for all the IO has some disadvantages:
a) namespace pollution: all opcodes are reserved words in Parrot
b) opcodes aren't overridable, that is you can't provide your own
'print' opcode for e.g. debugging
c) all such IO opcodes have to verify that the given PMC is
actually a ParrotIO PMC.
E.g.
new P0, .Undef # or .Integer, ...
print P0, "foo"
I'm in favor of using methods for almost all IO functionality:
P0.'print'("sample data\n")
Generally, I'm in favor of opcodes for simple, common operations, and
falling back to methods for more complex capabilities. It's overkill
to require people to write:
P0 = getstdout
P0.'print'(S1)
everywhere they would currently write:
print S1
One place I'm in favor of eliminating the opcode in favor of a method
call is the C<pioctl> opcode. I would also seriously consider it for
the socket opcodes, but we need to kick that one around a bit to see
if it really would be an improvement.
Combined with ...
* [ return code vs exception ]
... we can also check, if this was a void call or not (Parrot *does
have* the concept of a result context):
$I0 = pio.'print'("sample data\n") # return sucess (>=0) or
failure (<0)
pio.'print'("sample data\n") # throw exception on failure
That solution is problematic in the "unintended consequences"
department. Just because someone doesn't capture the return value
doesn't necessarily mean they want exceptions turned on for failures.
We would at least need to provide a flag for selecting exceptions vs
integer return codes. But, even that is probably too minimal.
A side note: many of these opcodes also have another return value in
addition to the integer error code, which makes the integer error
code interface clumsy.
* C<sockaddr> returns a string representing a socket address
[Nicholas] "I don't think that this is appropriate. It's IPv4
specific."
A more general SocketAddr PMC seems to be needed here.
Possibly. A smarter Parrot equivalent of a standard sockaddr structure:
http://www.awprofessional.com/articles/article.asp?
p=101172&seqNum=5&rl=1
Will it be used anywhere other than a call to C<bind>? If not,
there's probably a simpler way to handle it.
* [ seek, tell ] and 64bit values
We want sooner or later extended Parrot register types. One of
these would be a C<Int64>) Parrot register. We currently have:
op tell(out INT, in PMC)
op tell(out INT, out INT, in PMC)
Depending on the arch (32 vs 64 bits) one of these opcodes is
suboptimal. With a new "L" (Long) register type the functionality
could be handled transparently:
$L0 = pio.'tell'()
The register allocator would map 'L0' either to a pair (I0, I1) on
32 bit arch or just to 'I0' on 64 bit arch.
Actually the type mapping bits in pdd03 got extended to cope with
such register types.
For now I'll just note that the 2 integer forms for 64-bit offsets
may be deprecated in the future.
* [Nicholas] "Should the IO system provide symbolic lookup on
AF_* and PF_* constants.
IIRC at least one of these groups is OS dependant"
Any such constants that aren't the same on all architectures have
to be delt with at runtime, i.e. these constants can't be integers,
because integer constants are compiled into the bytecode in the
flavor of the compiling machine. That is: instead of
.include "xF_foo.pasm" # constants are resolved at compile time
we'd need something like:
load_bytecode "xF_foo.pasm" # postpone to runtime
We don't have a proper syntax for such (not so-) constants yet, but
it could just be:
pio = socket(".AF_UNIX", ...)
It seems like a more general problem than that. Like, you want a way
of flagging a constant when you define it as to whether it should be
substituted when compiling to bytecode or substituted when
interpreting the bytecode. (And a way of storing delayed constant
substitutions in the bytecode.)
Allison