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 ~ m...@livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps

_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to