
Resugaring – adding the syntactic sugar back into your program - jsnell
http://blog.brownplt.org/2016/02/06/resugaring.html
======
dalke
> x + y is syntactic sugar for x.__add__(y)

It's more complicated than that. If __add__ fails it falls back to __radd__:

    
    
      >>> class Spam(object):
      ...   def __radd__(self, first):
      ...     return str(first) + "radd"
      ... 
      >>> 5+Spam()
      '5radd'
      >>> Spam()+5
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      TypeError: unsupported operand type(s) for +: 'Spam' and 'int'
    

I skimmed the paper to see if it caught this nuance, but don't think it did.
("The desugaring follows a strategy similar to that of Python, by applying the
_plusmethod of the left subexpression to the right subexpression")

(The "." is another level of sugar, as "a.__add__" is equivalent to
"getattr(a, '__add__')". And "a" is sugar for 'a', as single quotes were in
Python before double quotes.)

> Syntactic sugar is when you define a piece of syntax in a language in terms
> of the rest of the language.

I believe that definition is incomplete. Is the "for" loop in C syntactic
sugar for a while() loop?

    
    
      for (x=0; x<n; x++) { ... }
    

is equivalent to

    
    
      x=0;
      while (x<n) {
        ...
        x++;
      }
    

or is the "while" loop syntactic sugar for a for loop?

    
    
      while (condition) {
         ...
      }
    

is equivalent to:

    
    
      for(;condition;) {
      }
    

Given the 'goto', both are sugar for an if/goto plus automatic goto target
label generator, so I'll repose the question in a C-without-goto variant
language.

~~~
justinpombrio
> > Syntactic sugar is when you define a piece of syntax in a language in
> terms of the rest of the language. > I believe that definition is
> incomplete.

Thanks for pointing that out. What I _really_ meant to say is:

"Syntactic sugar is when a piece of syntax in a language is defined in terms
of the rest of the language."

~~~
dalke
I think we can agree that given while() and for(), one is sugar because it can
be defined by the other.

My observation is that while it's possible to say there is sugar, it's not
possible to say which of the two is the sugar. That is, the while() can be
defined in terms {language - while()} and for() can be defined in term
{language - for()}.

~~~
justinpombrio
Sorry, I should have been more clear. I'm suggesting that you call a piece of
syntax syntactic sugar when it's actually _implemented_ in terms of the syntax
of the rest of the language. So it's possible that, e.g. while() is sugar in
one C++ implementation and for() is sugar in another.

That's just a question of terminology, though. There's a paper by Felleisen[1]
that makes what _you 're_ talking about precise. What you do is you ask
weather an extended language can express a piece of syntax with respect to the
base language. Your statement then becomes:

Let C* be C++, but without while() or for(). Then, (i) C* + for() can express
while() with respect to C _. (ii) C_ \+ while() can express for() with respect
to C*.

And all of this is made completely formal, and it's used to talk about the
expressive power of programming languages.

[1]
[http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.51....](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.51.4656&rep=rep1&type=pdf)

~~~
dalke
I agree, it's only a question of terminology. My comment was only that the
definition as given was incomplete.

Thanks for the link. It's too much beyond me to really follow, but I've no
doubt that such a definition is possible.

Would you say that Python's with statement is sugar? The PEP at
[https://www.python.org/dev/peps/pep-0343/](https://www.python.org/dev/peps/pep-0343/)
might suggest so, but Python has no way to generate new unique symbols for
variables, so the translation of:

    
    
      with open(filename):
         pass
    

can't trivially be converted to:

    
    
            mgr = (open(filename))
            exit = type(mgr).__exit__  # Not calling it yet
            value = type(mgr).__enter__(mgr)
            exc = True
            ...
    

because of possible name collisions.

~~~
justinpombrio
Renaming things isn't something you as a programmer should have to do; that
should be handled behind the scenes by the desugaring system / macro expander.
So yeah, I'd say that's a fine piece of sugar.

