HAS hasn't (worked) ...rethink CONSTRUCT?


#1

Back long ago–before I knew I’d somehow have spent years solving issues with this crazy language–we were looking for how to deal with the OBJECT and CONTEXT words.

It’s not very good to use nouns as verbs. It seems like you would write something like context: binding of 'some-word, not obj: context [x: 10 y: 20].

Rebol2 had CONTEXT, and then R3-Alpha added OBJECT as being slightly different:

object: func [
    "Defines a unique object."
    blk [block!] "Object words and values (modified)"
][
    make object! append blk none
]

context: func [
    "Defines a unique object."
    blk [block!] "Object words and values (modified)"
][
    make object! blk
]

So there’s a puzzling difference to add into the mix.

The HAS suggestion

There was increasing talk of OBJECT! having a “spec” like functions did. You’d be able to specify the types of the keys, or if things were public/private. Ren-C came along with questions of how to resolve the situation of wanting to have keys be null, yet being unable to literally represent nulls in blocks.

This environment gave rise to the idea of an arity-2 object constructor. The name CONSTRUCT (which had another purpose historically in Rebol) was thought to be taken for this arity-2 form. Then, in the same way that DOES was an arity-1 function, HAS would be an arity-1 constructor for objects.

foo: function [x [integer!] <local> y] [y: 1 | x + 1]
printer: does [print "hi"]

obj: construct [x [integer!] <private> y] [x: 10 y: 20]
cat: has [claws: yes | teeth: yes]

Sounds interesting in theory, in practice I haven’t cared for it

This has been around for quite a while, and I still use MAKE OBJECT! all the time. Part of that is compatibility, but also I just don’t know if it scans very well. Also, some problems with MAKE OBJECT! have been resolved with generalized quoting

What I have really been wanting would be an infix way of testing for fields in objects. Maybe even a soft quoting form. Making IN infix has some downsides, so HAS might be a fit there…and maybe CONSTRUCT is the better word to take to replace CONTEXT and OBJECT

>> cat: construct [claws: yes | teeth: yes]

>> cat has teeth
== #[true]

>> print either cat has (first [claws tusks]) ["scratch"] ["poke"]
scratch

>> cat has gun
== #[false]

Quoted or not (could just be cat has 'teeth, permitting cat has first [claws tusks] with no GROUP!), this just seems to fit better for the word, and something you’d use all the time (or at least I would). So I’ll propose the HAS/DOES parallel was a red herring, and it’s time to put that on ice.

…and then…what if CONSTRUCT could use “predicates”?

What if this new form of construct was willing to go field by field in the spec, and use a function on each step? (Not technically a predicate because it doesn’t return LOGIC!, I don’t know what we would call the more general form.)

>> foo: 10

>> construct .negative [x: foo y: (1 + 2)]
== make object! [x: -10 y: -3]

>> construct .quote [x: foo y: (1 + 2)]
== make object! [x: 'foo | y: '(1 + 2)]

This could give the lone CONSTRUCT the necessary polymorphism to load module headers as well as do any number of other things.

None of this gets us any closer to having specs for objects. But if you read Seeing ACTION!s as Generalized FRAME!-makers, it may be things should go the other direction, to where actions don’t have specs.

Thoughts?