[Python-ideas] Extending language syntax

Gregory Salvan apieum at gmail.com
Tue Nov 12 06:03:12 CET 2013


Thank you.

You're almost right, but there is misunderstanding.

I suggested generating value object by freezing object states and to have
object identities defined on their values instead of their memory
allocation.
so :
pi1 = keyword(3.14)
pi2 = keyword(3.14)
assert pi1 is pi2  # is true

and:
you = Person('Andrew Barnert')
andrew = keyword(you)
andrew.name = 'Dr. Sam Beckett'  # will raise an error.

It is value object not singleton because pi1 and pi2 are not of the same
instance.
This matter when doing concurrency but this is not the point as you can
cheat with "repr" or "hash".

I would focus mainly on how to extend language syntax and permit writing
code like:
'abc' should_equal 'abc'

Value object seems to me necessary to avoid side effects.

I miss your point about marshal/pickle and will dig it to understand.
I hope in future I can be more relevant.

Sorry for the inconvenience, thanks for taking the time to answer,
good continuation.




2013/11/11 Andrew Barnert <abarnert at yahoo.com>

> I could go through this point by point, but I think I can head it all off
> by explaining what I think is a fundamental misconception that's misleading
> you.
>
> In Python, variables aren't "memory locations" where values live, they're
> just names that are bound to values that live somewhere on their own.
> Rebinding a variable to a different value doesn't mutate anything. You
> can't make variables refer to other variables, and making two variables
> refer to the same value doesn't have the same referential
> transparency, thread safety, etc. issues as making a variable refer to
> another variable. For example, in the following code:
>
>     me = Person('Andrew Barnert')
>     andrew = me
>     me = Person('Dr. Sam Beckett')
>
> ... nothing has been mutated. In particular, the andrew variable is
> unchanged; it's still referring to the same Person('Andrew Barnert') object
> as before, not the new one.
>
> If I make the Person type mutable, and call a mutating method on it (or do
> so implicitly, by setting an attribute or a keyed or indexed member), then
> of course I can change the value, which will be visible to all variables
> referring to that value. But assignment does not do that.
>
> So, you already have almost everything you want. You can create new
> immutable types and global singleton values of those types. Or create
> Enums. Or just create singleton objects whose type doesn't matter, which
> are immutable and compared by identity, just by calling object(). All of
> this is trivial.
>
> Taking one of your examples:
>
>     Pi = 3.14159
>
> ... gives you everything you wanted, except for the fact that you can
> accidentally or maliciously rebind it to a new value. It's already an
> immutable, thread-safe constant.
>
> You can even make a variable name un-rebindable with a module import hook
> that produces a custom globals, if you really want to, although I can't
> imagine that ever being worth doing.
>
> The only additional thing a keyword gives you is that the compiler can
> prevent you from rebinding the name to a different value, at compile time
> rather than run time. That's it.
>
> Meanwhile, the disadvantage of allowing new keywords to be defined for
> immutable constants is huge. You could no longer compile, or even parse,
> any code without checking each token against the current runtime
> environment. That makes the parser slower and more complicated, introduces
> a dependency that makes it hard to keep the components separate, makes pyc
> files and marshal/pickle and so on useless, makes it much harder for code
> tools to use the ast module, etc. All for a very tiny benefit.
>
> Sent from a random iPhone
>
> On Nov 11, 2013, at 3:20, Gregory Salvan <apieum at gmail.com> wrote:
>
> Hi all,
> I've just joined you, I hope I'll not make you loose your time with
> questions already covered.
> Sorry, if my suggest represents lot of work (certainly too much) and about
> my lack of knowledge about internal implementation, but I hope opening a
> discussion can help.
>
> I would suggest to introduce a new statement to provide a way to extend
> language syntax.
>
> Abstract:
> While reading this article about None history<http://python-history.blogspot.fr/2013/11/story-of-none-true-false.html>I realised I was not alone to wonder about some aspect of the language.
>
> Some of these are:
> - constant and immutability
> - null object and "None is a singleton"
> - readability of code
>
> *Constant:*
> It's a convention, no matter with that.
> My question is more if there is no memory overuse to have fixed values
> that behave as variable.
>
>
> *Null Object:*
> NoneType is not overridable.
> Having null objects instance of NoneType wouldn't make sense ?
> Can't assign keywords so "None is a singleton".
> Wouldn't it be more simple to have "keyword" type and be able to assign a
> keyword to a variable ?
> With an object hierarchy like: keyword <- ReservedKeyword
> I find it can make clearer why some keywords are reserved without changing
> actual behaviour.
>
>
> *Readability of code:*
> I have shouldDsl <http://www.should-dsl.info/> use case in mind.
> The introduction illustrate my thought:
> "*The goal of Should-DSL is to write should expectations in Python as
> clear and readable as possible, using an “almost” natural language (limited
> by some Python language’s constraints).*"
>
> I find ShouldDsl perturbing, as the aim is laudable but the implementation
> stays a hack of the language.
> I see the influence of functional paradigm in this syntax and agreed with
> the fact it becomes a "must have".
>
> I love Python syntax and find, it has very few limits, but maybe it can be
> improved by reducing some constraints.
>
> One concerns in extending syntax is that the language can evolve on users
> usage.
> I see it like an open laboratory where developpers experiments new
> keywords like "should" implemented in their favorite language and when this
> keyword is largely accepted by the community it can finally integrate the
> core.
>
> *A solution*:
> I was first thinking of a statement like "Instance" to declare an
> immutable object with a single instance (like None), but I then consider
> how it would be great to be able to extend the syntax.
> I thought the keyword "Keyword", which exists in clojure for example<http://clojure.org/data_structures#Data%20Structures-Keywords>,
> can do the job.
>
> A first implementation can be:
>
> Keyword <name>(<keyword, literal or object>):
>   field = <something>  # fixed value: self.field = "something" will raise
> an error
>   def behaviour(self, *args, **kwargs):
>     # do something
>   def __get__(self, left, right, block_content):
>     # what to do when accessing keyword
>
> Inline implementation:
> Keyword <name>(<keyword, literal or object>)
>
>
> *Examples of use:*
>
> *Constant*:
>   Keyword Pi(3.14159)
>
> *Null Object* and immutable objects:
>   Class Person(object):
>     def __init__(self, name):
>       self.name = name
>
>   JohnDoe = Person(name="anonymous")
>
>   Keyword Anonymous(None, JohnDoe)
>
>   Anonymous.name = "JohnDoe"  # raise an error
>   assert isinstance(Anonymous, type(None))  # is true
>
>
> As Anonymous is immutable , it is also thread safe.
> The mecanism which consist of freezing an object can be applied in other
> situation.
>
> An interesting approach can be to define keywords identity throught a hash
> of their value, like value object.
>
> *Should keyword*:
>
> Keyword ShouldEqual(keyword):
>   def __get__(self, left, right, block):
>     if left != right:
>       raise AssertError()
>
> ### weird examples:
>
> *Multiline Lambdas*:
> Keyword MultilineLambda(keyword):
>   def __get__(self, left, right, block_content):
>     def multiline_lambda(*args, **kwargs):
>       self.assert_args_valid(right, args, kwargs)  # compare "right"
> (tuple) with args and raise exception in case not valid
>       return self.run(block_content, args, kwargs)  # "run" is a shortcut
> because I don't know which type is the most appropriate for block content
>     return multiline_lambda
>
>   divide = MultilineLambda a, b:
>     if b == 0:
>        raise MyDivideByZeroError()
>     return a/b
>
> *Reimplementing else*:
> Keyword otherwise(keyword):
>   def __get__(self, left, right, block):
>     if left: return  # left is the result of "if" block
>     self.run(block)
>
> if something:
>   # do something
> otherwise:
>   # other
>
> Whereas this example is weird, it seems to me that we can better figure
> out what language do.
>
>
> Thanks all to have kept python open and give us opportunities to freely
> discuss about its future implementation.
>
> Have a nice day,
> Grégory
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131112/7b6d0a99/attachment-0001.html>


More information about the Python-ideas mailing list