defRead was defined like this:

defRD=: 2 :0
  ('read_',m)=: v
)

So,
'char' defRD (3 :0)
 (POS=:POS+1) ] FILEBUF{~POS
 :
(POS=:POS+x) ] FILEBUF{~POS+i.x
 )

is equivalent to

read_char=: 3 :0
 (POS=:POS+1) ] FILEBUF{~POS
 :
(POS=:POS+x) ] FILEBUF{~POS+i.x
 )

In other words, it's just a mechanism for a somewhat consistent naming
scheme.  That said, like all code, I waffle about its usefulness.

The parenthesis around 3 :0 are because of the precedence rules for
parsing conjunctions. If I did not have those parenthesis in place,
that line would be equivalent to:

('char' defRD 3) : 0

which would be an error.

The parenthesis forces the (3  :0) to parse before defRD is examined.
And 3 :0 becomes a verb whose definition is supplied on the following
lines.

The MessagePack spec looks like a fun little project. That said, note
that some of those representations will contribute values which will
not necessarily be efficient to represent in J. That should not be a
problem, because such values are rare.

For example, "unsigned 64 bit integer" will require extended precision
to represent the full range of values.

And I think I'd implement in two passes. First, I'd build up my
repertoire of numeric parsing routines. And then I'd implement a
gerund of 256 of them (each of which which gets the current character
and however many relevant subsequent characters) and appends them to
an array.

Of course, it'll not be that simple. To be completely generic you'd
need to put each read value in a box, which will be tremendously
inefficient and not particularly useful. But that's OK for a reference
implementation. In fact, most "efficiency" claims on computing
platforms are somewhat misleading - they are efficient for specific
contexts at the expense of being inefficient for other contexts. But
you have to tackle projects like that to get a feel for them.

The thing about efficiency is that most of the time it doesn't matter.
And, when it does matter, you need to spend some time understanding
what's going on (finding bottlenecks and alleviating them).

The other thing about efficiency is that correctness matters more than
efficiency does. (Otherwise you wind up doing the wrong thing really
fast.) A sense of humor can help, sometimes.

Anyways, try it out, see how far you get, and take a look at what you
come up with. It will probably benefit someone at some point, which
can be a good thing. And the practice can't hurt.

Thanks,

-- 
Raul

On Fri, Jan 23, 2015 at 10:23 PM, Jon Hough <[email protected]> wrote:
> I'm not sure I understand the syntax here:
>
> 'char' defRD (3 :0)
>  (POS=:POS+1) ] FILEBUF{~POS
>  :
> (POS=:POS+x) ] FILEBUF{~POS+i.x
>  )
>
> What is 'char' here? Also the (3:0) seems out of place. What the brackets?
>
>
> One of the things I am actually trying to do is to write a MessagePack ( 
> http://msgpack.org/  ) implementation in J.
>
> MessagePack is a serialization format, that is (in theory) more compact than 
> JSON.
> There are implementations in pretty much every popular language.
> The specification is here 
> https://github.com/msgpack/msgpack/blob/master/spec.md
> For example, my first draft for floats can be "packed" by
>
> float64 =: 'cb' NB. constant byte for floats (64-bit floats)
>
>
>
> convertFloat =: |."1@:,@:(|."1)@:hfd@:(a.&i.)@:(2&(3!:5)) NB. convert float 
> to hex string
>
>
> packFloat =: float64&, @: convertFloat NB. append the float byte
>
> The specification is not terribly complicated, and on GitHub you can read 
> implementations that are only 500~ish lines long in most languages.
>
>
>
>
>
>
>
>
>
>
>
>
>
>> Date: Sat, 24 Jan 2015 01:45:06 +0900
>> From: [email protected]
>> To: [email protected]
>> Subject: Re: [Jprogramming] J Equivalent of Python Struct.Pack/Unpack
>>
>> Thanks,
>> I am going to try to read through that code tomorrow. It looks interesting.
>>
>> --- Original Message ---
>>
>> From: "Raul Miller" <[email protected]>
>> Sent: January 24, 2015 1:00 AM
>> To: "Programming forum" <[email protected]>
>> Subject: Re: [Jprogramming] J Equivalent of Python Struct.Pack/Unpack
>>
>> Here is some example code I have used to extract from streamed object files:
>>
>> FILEBUF=: '' NB. is read or mapped from file
>> POS=: 0      NB. marks next unread byte
>>
>> defRD=: 2 :0
>>   ('read_',m)=: v
>> )
>>
>> NB. readers - left argument of dyad is vector length to read
>>
>> 'char' defRD (3 :0)
>>   (POS=:POS+1) ] FILEBUF{~POS
>> :
>>   (POS=:POS+x) ] FILEBUF{~POS+i.x
>> )
>> 'byte' defRD (a.i.read_char)
>>
>> ic=: 3!:4
>> 'Flags' defRD (3 :0)
>>   (POS=:POS+2) ] {. 0 ic FILEBUF {~ POS+i.2
>> :
>>   (POS=:POS+2*x) ] 0 ic FILEBUF {~ POS+i.2*x
>> )
>>
>>
>> fc=: 3!:5
>> 'float' defRD  (3 :0)
>>   (POS=:POS+4) ] {. _1 fc FILEBUF {~ POS+i.4
>> :
>>   (POS=:POS+4*x) ] _1 fc FILEBUF {~ POS+i.4*x
>> )
>>
>> 'IndexString' defRD [: NB. don't ask
>>
>> 'int' defRD (3 :0)
>>   (POS=:POS+4) ] {. _2 ic FILEBUF {~ POS+i.4
>> :
>>   (POS=:POS+4*x) ] _2 ic FILEBUF {~ POS+i.4*x
>> )
>>
>> NB. bools have a dual existence:
>> NB. a true/false value (a count - 0 or 1 times)
>> NB. a literal value (an arbitrary number)
>> 'bool' defRD ((,"0~*)@read_int)
>>
>> 'Ptr' defRD read_int
>>
>> 'Ref' defRD read_int
>>
>> 'short' defRD (3 :0)
>>   (POS=:POS+2) ] {. _1 ic FILEBUF {~ POS+i.2
>> :
>>   (POS=:POS+2*x) ] _1 ic FILEBUF {~ POS+i.2*x
>> )
>>
>> 'ushort' defRD (3 :0)
>>   (POS=:POS+2) ] {. 0 ic FILEBUF {~ POS+i.2
>> :
>>   (POS=:POS+2*x) ] 0 ic FILEBUF {~ POS+i.2*x
>> )
>>
>> 'unsigned' defRD ((2^32) | read_int)
>> 'uint' defRD read_unsigned
>>
>> NB. special compound (or other) defs
>> 'SizedString' defRD (3 :0)
>>   length=. read_int ''
>>   value=. length read_char ''
>> :
>>   NB. boxing needed to preserve length of strings
>>   x <@read_SizedString Repeated ''
>> )
>> 'string' defRD read_SizedString
>>
>> ...
>>
>> As you can see, this is rather bulky (for J). The full code is even
>> bulkier (and never went anywhere, though maybe I'll get back to it at
>> some point).
>>
>> This winds up being a line of code for every item that you want to
>> read. But once you have defined a word that reads a structure from
>> file you can just use it and not worry too much about its
>> implementation (as long as the implementation is correct).
>>
>> The code to write things back out winds up being about the same amount of 
>> bulk.
>>
>> I'm not sure if this is useful to you, but I'm not using it right now,
>> so if you get some use from it that means my time writing it was not
>> entirely wasted.
>>
>> Thanks,
>>
>> --
>> Raul
>>
>>
>> On Tue, Jan 20, 2015 at 10:42 AM, Jon Hough <[email protected]> wrote:
>> > Python has a useful module called struct
>> > https://docs.python.org/2/library/struct.html
>> > which is useful for converting strings to packed binary data.
>> > e.g.
>> > data = struct.pack('B', someHexString)
>> >
>> > Does J have an equivalent or similar function / verb?
>> > I spent a bit of time looking, but couldn't find anything.
>> >
>> > Example usage would be sending data over a network.
>> >
>> >
>> >
>> > ----------------------------------------------------------------------
>> > For information about J forums see http://www.jsoftware.com/forums.htm
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>> ----------------------------------------------------------------------
>> For information about J forums see http://www.jsoftware.com/forums.htm
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to