English Like?

Mark Waddingham mark at livecode.com
Thu May 25 10:57:32 CEST 2017


On 2017-05-24 19:27, Mark Wieder via use-livecode wrote:
> On 05/24/2017 08:11 AM, Martin Koob via use-livecode wrote:
>> I agree that LiveCode script should become more English like as time 
>> goes on
>> not only with english words but also with more natural(or intuitive)
>> grammar.
>> 
>>> From your examples I think it would be more natural to type.
>> 
>>     put the third index of tNumericArray into tFoo
> 
> The one that's always bugged me is
> 
> put item 2 of the rect of someObject into tVar
> 
> Rects have a defined order of items, and I can never remember whether
> it's "left,top..." or "top,left..." and I end up looking it up every
> time. I'd love to have a more normal (all right, English-like...
> there... I've said it) way to remember and write this.

This is a very interesting example on two levels...

The first is in regards to 'English-like'-ness. In English we uniformly 
use 'top left' to describe, well, the 'top left' point of something. 
However, mathematical convention means that points are always 'across 
then down' - i.e. x, y.

The English phrase for this concept is 'top left' because there is a 
rule in English about the order of adjectives - interestingly if you get 
the order wrong, it just *sounds* wrong (e.g. mad old women vs old mad 
women). Of course, for non-native English speakers (as Tiemo pointed out 
a few days ago) it probably makes no sense at all *unless* you remember 
that rather odd English rule about adjective order.

[ Indeed, I suspect other languages also have a similar rule, but I 
don't recall ever being taught such a thing in French, German, Latin or 
Ancient Greek (which could be a facet of time admittedly - it being 20 
yrs since I studied them), but perhaps it is just something which we 
'pick up' through repetition until it gets embedded in deep parts of our 
brains. ]

So we do have the (syntactically) rather (apparantly) inconsistent and 
unintuitive:

   set the topLeft of button 1 to tLeft, tTop

However, conceptually it is 'correct' - topLeft is the correct way to 
express the concept *in English* and tLeft,tTop is how the concept is 
expressed in geometry.

If we were to use leftTop instead, it would be consistent with the 
'syntax' (if you like) of the underlying concept, but inconsistent with 
the 'syntax' for it in English.

End result: there is friction between the abstract concept (a point is 
x,y) and how it is expressed in language (English mandates top-left).

Now, I'm not sure this is 'fixable' in a way which would be 'better' for 
everybody, however, the name of the concept (topLeft) used in LiveCode 
is perhaps not the real problem... The problem comes (as Mark rightly 
points out) when you try and *manipulate* the thing you get when you ask 
for the rect, or the topLeft...

You have to do:

   put item 1 of tRect into tLeft
   put item 2 of tRect into tTop
   put item 1 to 2 of tRect into tTopLeft

Here we have what you might call 'magic constants' (1 and 2) - you have 
to *know* what those constants are, and use them explicitly to get the 
right thing (Alex pointed out in this thread that you could just define 
constants and/or globals for them - which works, but isn't exactly 
intuitive unless you know to do that).

A much more intuitive way to do this would be to be able to do:

   put the left of tRect into tLeft
   put the top of tRect into tTop
   put the topLeft of tRect into tTopLeft

Of course the issue here is that (in LiveCode) points and rectangles 
(and colors) are just strings - there is no extra information there. So 
when the engine tries to evaluate:

   the left of tRect

All it has to work with is the content of tRect which is a string of 
four comma separated numbers - but a string of four comma separated 
numbers could be a variety of things and not necessarily a rect.

One suggestion which immediately comes to mind is - oh we could just add 
some extra invisible 'meta' information to 'the thing returned by the 
rect property' marking string as a StringyRectangle so the engine 
*knows* it is a rectangle. However, that doesn't work because that meta 
information would be immediately lost if you concatenate your rect onto 
another string:

   repeat for with i = 1 to the number of controls
     put the rect of control i & return after tControlRectList
   end repeat

Something which is done all the time in LiveCode. Furthermore, if the 
string came from somewhere which is not a rect property, then it 
wouldn't have it either - e.g. the rect is a substring of a text file 
from an external source.

However, what we could potentially exploit is the syntax of the thing in 
the string. At the moment when you do:

    the something of tString

The engine interprets this as a property get on an object - it converts 
tString to an object reference (internally) and then gets the property 
'something'. The syntax of an object reference is fixed. e.g.

    control 3
    field 2 of card 4
    button "moomin" of card "moominland"

It also happens to be completely disjoint from the 'syntax' of a rect 
string which is:

    <number>,<number>,<number>,<number>

And a point string which is:

    <number>,<number>

Now, we can consider every piece of syntax we use to be a mapping from 
the syntax to a function call. In this case:

   'the' PROPERTY 'of' EXPR

Maps to:

    MCObjectGetProperty(ResolveObject(Expr), PROPERTY)

If Expr is not an object reference string (i.e. in the form we know and 
love), then it is an error - you can't convert '10,20' to an object 
reference. What you *can* do is 'generalize' how the 'property get' 
syntax binds.

Indeed, we have *three* methods we would like it to bind to:

   MCPointGetProperty(POINT, PROPERTY)
   MCRectangleGetProperty(RECTANGLE, PROPERTY)
   MCObjectGetProperty(OBJECT, PROPERTY)

The difference here is the 'type' of the thing we are getting a property 
from.

As I said above, as luck would have it, the syntax (as a string) for 
object references, rectangles and points are disjoint... I can write an 
unambiguous function:

   MCParseTargetString(STRING) returns (POINT or RECTANGLE or OBJECT)

So execution of:

   the prop of string

Would do:

   put MCParseTargetString(string) into tThing
   switch typeof(tThing)
     case POINT: MCPointGetProperty(tThing, prop)
     case RECTANGLE: MCPointGetProperty(tThing, prop)
     case OBJECT: MCObjectGetProperty(tThing, prop)
   end switch

Moreover we can play this game with any 'type formatted as string' as 
long as the syntax for each of the kinds of string we might want to deal 
with are disjoint.

TL;DR version:

It looks like that we could have:

   put the left of the rect of tObject
   put the x of the topLeft of the rect of tObject
   ...

In a way which cleaves into the LCS as it is now with no friction or 
backwards-compatibility concerns - a natural extension of how things 
work now.

Warmest Regards,

Mark.

P.S. We can actually go slightly further - for any 'type' in LiveCode 
(e.g. point, rectangle, color) which is expressed as a sequence of comma 
separated things; as long as the names of the sub-parts (i.e. point has 
x,y, rectangle has 
left;top;right;bottom;topLeft;topRight;bottomLeft;bottomRight, color has 
red;green;blue;alpha) are disjoint the idea works.

-- 
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps



More information about the use-livecode mailing list