Sample Custom Datatype Idea: Sound

As an example, lets build a simple custom structure:

[[internal structures][data1][data2][data3][data4]]

I want that that head corresponds to data1, and index? returns1 when positioned there.

If you have an internal action called "reposition" and "get-position" belonging to that datatype, Ren-C should look at the block if it carries an additional management object. If it contains "reposition" and "get-position" it should use this custom functions to override the standard ones for the datatype. You code them so that they do not move before data1, and you have a special structure which acts transparently to the standard Ren-C working.

Now lets take:

sound: [[header] size: 5000 modified-by: "HF" sound: #A45ACF...  [tail-data]]

It is your structure to store a sound.

you want that at set operation using ':' will be written raster-image: content, so that

sound: load %mysong.wav

You add a custom management object with overwrites the set operation and also all the others regarding pick/length?/poke... and so on, so that your Ren-C script works with the usual syntax, which is internally manage by from you replacement actions, translating everything to the new coordinates and operation system

Obviously, you could have additional action to be available to the developers which do not replace the internal actions but they could be called with syntax like:

do-custom data 'method [parameter parameter]

or having a special path like sound/#/fourier-trasform

You could do something like that now with the PORT! datatype, though awkwardly. The port actors return whatever you want them to:

my-sound: make port! [
    scheme: 'simple-sound
    [data1] [data2] [data3] ...
]

; in Rebol 3, the only requirement creating a port with a block
; is that it begin [scheme: 'scheme-name ...], can be followed
; by any data sequence accessible to INIT/actors via
; PORT/SPEC/REF

length-of my-sound
; == whatever your 'length-of actor returns

sound-suite/play my-sound
; can check: port? my-sound; my-sound/scheme = 'simple-sound

One of the reasons I think PORT! is misunderstood is that this type of usage isn't really 'port' in the traditional sense of an interface between systems, I'd suggest this falls under the traditional conception of Rebol objects which I think could be improved upon. Hence...

This sort of comports to the Javascript object model and is the intent behind my Class proposal. The efficiency in this model is that functions are not copied from the prototype to the kids, nor are default values—the kids only contain values where they deviate from the prototype. On further consideration, I would likely add verb actors to the Class model and possibly methods of handling iteration that it can be traversed by the *-EACH functions.

As an aside, Javascript objects (including arrays) are entirely built on associative arrays (MAP!) with string keys, there's no binding (the value of THIS within a function is determined by how it is called and can be overridden by .APPLY()/.CALL()). A path myobject.thing is shorthand for myobject['thing'], similarly myarray[0] is shorthand for myarray['0']; if myobject has no 'thing' key, JS will keep looking up the prototype chain until it reaches Object.prototype (which is where, e.g. apply/call live) and will return undefined if it's not found. In this way it avoids Rebol OBJECT! needing every key in each kid, and instanceof gives you some assurance that your object value has the requisite set of method (there's no equivalent of this in Rebol objects, slight equivalent in Rebol ports—value/scheme = 'myscheme).

Thanks for the ports description, It is interesting but not perfect. I don't see a way to override : and also I have to investigate in other operations.

The difference is that while actions copy dispatch to the datatype without paths, you need paths in ports or a premise like insert port...

I have read tha LUA has something similar with Metatables and Metamethods but I have to go deep in it.

There's two ways to initiate ports in Rebol/Ren-C currently—1) by URL/File datatypes and 2) by block [scheme: 'thing ...dialect of your choice...]. If by overriding : you mean something along the lines of KWATZ!, that'd be a huge language design decision. For now ports are the closest thing you have to a custom datatype—I think there's another way but it needs to be fleshed out more as an approach.

I'm not quite sure what you mean by this—do you mean that going the port direction means your custom values don't have their own methods? If that's more important than being able to use the standard verbs (per your example, PICK, LENGTH, INSERT, REMOVE, etc.), wouldn't plain objects work better instead? With ports as-is, you get to define the meaning of these verbs, so if you say insert mysound [...random data...] you can throw an error if it doesn't conform to your specification.

Would be curious how this compares to Javascript's approach...