Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Documenting Rebol's dialect

I can document a function like this:

f: func [
    "a description"
    arg1 [string!] "a description of an argument 1"
    ][
    arg1
    ]

I can use ?/help in order to retrieve informations about the the function (a description, a usage, the argument list, a description of each argument and it's type)

? f
USAGE:
    F arg1

DESCRIPTION:
     a description
     F is a function value.

ARGUMENTS:
     arg1 -- a description of an argument 1 (Type: string)

I cannot document dialects like this. Is there an automatic way to document dialects (like func does)? Do I have to do this manually?

like image 312
Darek Nędza Avatar asked Sep 26 '22 21:09

Darek Nędza


1 Answers

There's nothing for it currently, but it's a good idea. So good that someone has suggested it before. :-)

Do I have to do this manually?

You can manually write a new generator which defines your "dialect spec" format. Then either do something like give it a HELP command, or extend HELP to recognize it.

Very short example to demonstrate a group of techniques which may come in handy in doing something like this (not all expected to be obvious, rather to hint at the flexibility):

make-dialect: function [spec [block!] body [block!]] [
    return function ['arg [block! word!]] compose/deep/only [
        case [
            arg = 'HELP [
                foreach keyword (spec/keywords) [
                    print [keyword "-" {your help here}]
                ]
            ]

            block? arg [
                do func [arg] (body) arg
            ]

            'default [
                print "Unrecognized command.  Try HELP."
            ]
        ]
    ]
]

So there's your function that takes a dialect spec and makes a function. Once you've got your generator, using it can be less manual:

mumble: make-dialect [keywords: [foo baz bar]] [
    print ["arg is" mold arg]
]

>> mumble help
foo - your help here
baz - your help here
bar - your help here

>> mumble [<some> [dialect] {stuff}]
arg is [<some> [dialect] {stuff}]

The techniques used here are:

  • Soft Quoting - Usually you would have to say mumble 'help to "quote" the help as a lit-word! to get it to pass the word! to mumble (as opposed to running the default HELP command). But because arg was declared in the generated function as 'arg it was "soft quoted"...this means that words and paths will not be evaluated. (Parens, get-words, and get-paths still will be.) It's a tradeoff because it means that if someone has a variable they want to pass you they have to say :var or (var) as the argument instead of just var (imagine if the block to pass the dialect is in a variable) so you don't necessarily want to use it...but I thought it an interesting demo to make mumble help work without the lit-word!

  • Deep Composition - The spec and the body variables which are passed to make-dialect only exist as long as make-dialect is running. Once it's over, they'll be gone. So you can't leave those words in the body of the function you are generating. This uses COMPOSE/DEEP to evaluate parens in the body before the function generator runs to make the result, effectively extracting the data for the blocks and stitching them into the function's body structure.

  • Reusing Function's Binding Work - The generated function has a spec with a parameter arg that didn't exist at the call site of make-dialect. So arg has to be rebound to something, but what? It's possible to do it manually, but one easy way is to let FUNC do the work for you.

Those are some of the techniques that would be used in the proposed solution, which seeks to not only document dialects but provide an easy method by which their keywords might be remapped (e.g. if one's Rebol system has been configured for another spoken language).

like image 51
HostileFork says dont trust SE Avatar answered Oct 26 '22 21:10

HostileFork says dont trust SE