English Like?

Mark Waddingham mark at livecode.com
Wed May 24 08:13:25 EDT 2017


On 2017-05-17 22:41, William Prothero via use-livecode wrote:
> Folks:
> It can be difficult for long term users of an application to
> appreciate the “exceptions” to the philosophy of a dev app. I think
> the livecode community is affected by “familiarity” over clarity
> sometimes. For years (when Director was a viable dev platform), I had
> a negative feeling about Hypercard type syntax. I had done some pretty
> extensive programming in Hypercard and Supercard too. I liked the way
> Director worked. I liked that it did not insult my intelligence by
> requiring “put 3 into x” instead of the universal "x=3” syntax that
> all algebra students lewarn in gradeschool, When Director died, I
> looked around, held my nose, and jumped to livecode, and now I’m glad
> I jumped that initial negative barrier. But, I take exception to the
> many claims that livecode is “english-like” (in spite of the many
> “english-like” commands), especially if you want to do the advanced
> work that most of the users do.

Finally getting around to responding to this, as it is something which
interests me... Specifically, we often hear about how LC's syntax
'insults intelligence' or is 'babyish' etc. However, I have to say that 
I've
never understood *why* really.

The only two reasons I really come up with are:

   1) The 'high-priest' argument: programming languages should use 
somewhat arcane and obscure means of expression so that it limits who 
would want to / can use them.

   2) The 'burnt by limited English-like systems in the past' argument: 
the incorrect association between being 'English-like' syntax wise, and 
not being a full, general, programming environment (the point here being 
the limits are in the implementations, not in the concept).

I'd be really quite interested to know what other people think here.

In particular, the use of 'put X into Y' rather than 'X = Y' comes up
periodically.

<nit-picky-mathematician>
The mathematician in me has to point out that the argument that 'X = Y' 
is 'better because we learn it in algebra' is technically erroneous. 
Algebra (and mathematics in general) operates on pure substitution - all 
values are singletons and the *only* thing which is equal to any value, 
is the value itself. Put another way, algebra does not have 'variables' 
in the sense we mean it in computing, 'X = 3' really does mean that X 
*is* 3, not that it should have 3 assigned to it, hence in a 
mathematical expression you can replace every occurrence of X *with* 3. 
(Modelling computer languages in the pure world of mathematics requires 
a bit of mental leap - what we consider a procedure is transformed into 
a function on the set of all possible states of the computer it is 
running on, rather than as sequential actions which occur on a single 
mutable state). Indeed, many languages choose ':=' for assignment and 
not '=' for this reason (it also means you don't have to use '==' for 
equality, and can use '=' which is a much better fit with what we do 
learn in Algebra).
</nit-picky-mathematician>

Okay, so back to the point, if one wants a language to be readable and 
easily understandable it needs to be consistent. So, in isolation, 
perhaps have 'X := Y' for assignment might seem more economic. However, 
LiveCode's 'put' command is actually a fair bit more flexible. You can 
do:

   put X into Y
   put X after Y
   put X before Y

So if you have code which does:

   put "foo" after X
   put X into Y
   put "bar" before Y

You end up with:

   put "foo" after X
   Y := X
   put "bar" before Y

Here you end up having to do mental contortions because the sense of the 
'before' and 'after' forms are opposite to the assignment (copy) form - 
easy readability vanishes. In particular, put flows from left to right, 
in contrast to the right to leftness of ':='.

Certainly one could replace 'put X into Y' with 'X := Y', and even 'put 
X after Y' with 'X &= Y' - but what about before? 'X =& Y'? e.g.

   X &= "foo"
   Y := X
   Y =& "bar"

This looks really quite subtle to me, much easier to miss that one is 
'append' and the other is 'prepend'.

One thing I think LiveCode does do because of its slightly more verbose 
syntax is that it encourages readability (and as a result perhaps more 
maintainability) in code - something which other languages do not 
directly... Indeed, writing C programs which are readable and 
maintainable can take a great deal of time to learn *how* to do well - 
the language in and of itself doesn't really help you much at all. (That 
isn't to say it isn't possible to write unreadable code in LiveCode, 
because it clearly is - muddy abstractions can cause that as much as the 
syntax itself, but I'd like to think that LiveCode lends itself to more 
readable code by default... As subjective as that might be!)

Of course, LiveCode syntax isn't perfect - it has [] for array access 
for example - it might be nice to be
able to do:

    put index 3 of tNumericArray into tFoo
    put the foo of tAssocArray into tBar

Which is perhaps the way I'd suggest the language should go - replacing 
what we currently use symbols (operators) for with 'English-like' forms.

It should be noted in all of this that syntax is just sugar (but don't 
take that as meaning that sugar isn't important - if you forget the 
sugar in recipes you often end up with inedible things). A handler such 
as:

   command Foo
     put the long id of control "Foo" into tVar
     put the backColor of tVar into tVarBackColor
     set the backColor of char 3 to 5 of field 3 to tVarBackColor
   end Foo

Could be equivalently written (in a more 'traditional' syntax) as:

   void Foo()
   {
      tVar := control("Foo")
      tVarBackColor := tVar.backColor
      field(3).char(3, 5).backColor := tVarBackColor
   }

Indeed, it is my feeling that (if there was value in doing so in the 
future) then a more 'traditional' variant syntax for LiveCode would be a 
better way to go than trying to mix 'English-like' syntax more with 
non-'English-like' syntax - that way you keep consistency within both 
'syntax worlds', but still allow you to view them in either form. In 
this case it would be critically important to maintain direct 1-1 
mappings between the two different syntaxes - neither would be more 
expressible than the other. That way, it would be a switch in the editor 
which form you see, thus meaning we wouldn't bifurcate the community in 
terms of what code people could and could not understand. (It should be 
noted that the semantics would be identical, a variant syntax might 
*look like* JavaScript, but it wouldn't actually be JavaScript which has 
quite different rules about how values work and flow).

One of the achievements of the refactor we did (resulting in 7.0) was to 
ensure that there was a complete and clear split between the code which 
parses and dispatches LiveCode syntax, and the implementation of the 
action itself (all LiveCode's implementation of the action of syntax is 
now held in a large collection of C++ functions with well defined 
prototypes; rather than embedded in the VM's abstract syntax nodes). 
This work is one part of making this possible and various parts of the 
work done for LCB make up some other parts. It has gone from being 
something which could be considered a fantasy, into something which 
could be a reality.

Indeed, at some point that might let us go further - allow LiveCode's 
full functionality to be accessed directly from *other* languages in a 
manner natural to them... This is the reverse of the Infinite LiveCode 
'FFI' project but the abstract principal is the same - e.g. creating 
natural JavaScript bindings around LiveCode's functionality at the 
'syntax action' level'. However, that is perhaps a story for another 
day...

Just my two pence :)

Warmest Regards,

Mark.



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




More information about the use-livecode mailing list