[Python-ideas] Re: Lazy Type Casting

2020-12-10 Thread Mathew Elman
Steven D'Aprano wrote:
> On Wed, Dec 09, 2020 at 12:05:17PM -, Mathew Elman wrote:
> > Steven D'Aprano wrote:
> > On Tue, Dec 08, 2020 at 11:46:59AM -, Mathew
> > Elman wrote:
> > I would like to propose adding lazy types for
> > casting
> > builtins in a 
> > lazy fashion. e.g. lazy_tuple which creates a reference to the 
> > source iterable and a morally immutable sequence but only populates 
> > the tupular container when it or the source is used.
> > What are your use-cases for this?
> > Does this include things like lazy_list, lazy_float,
> > lazy_bool, 
> > lazy_str, lazy_bytearray etc?
> > I would say yes, it should include these types as well.
> > The use case is for when you are casting between types a high number 
> > of times to pass them around, especially into another type and back.
> > I would say, don't do that. If you have a list, and you pass it to 
> another function after converting to a tuple, why would you take that 
> tuple and convert back to a list when you already have a list?
> For types like casting back and forth between float and int, there will 
> be data loss.
> Even if there is not, the overhead of creating a "lazy proxy" to the 
> float is probably greater than just converting.
I see what you mean here, I think my initial thought was more towards container 
types rather than ints and floats, I said these should be included because I 
saw no reason why not. Thinking about it, for int and float types it makes less 
sense, because you have no great saving, whereas for a container type, you can 
increase the reference count by 1 instead of N. 

> > How do these
> > hooks freeze the list?
> > they don't freeze the list, they freeze the values in the lazy_tuple 
> > when the list is mutated, so when mutating the list, the values in the 
> > tuple are set (if they have not been already), so that they aren't 
> > also mutated in the lazy_tuple.
You seem to be referring to the lazy_tuple as the hook, I am saying that _I_ 
could implement a lazy class if hooks existed. i.e. I could make a class 
`LazyTuple` that when instanced with a list, creates and stores the hooks on 
itself. 

> > How is this supposed to work in practice?
A method e.g. `create_hook(method, callback)` would return a concrete reference 
to the hook, and uses a weak reference to know if it needs to execute the 
callback (meaning that it would only add the overhead of a check for callbacks 
if the concrete reference still existed).

> > Where does the hook live? When 
> is it called? What does it do?
> How does the lazy tuple know that the list's setitem has been called?

It knows because of a hook? This is my whole point about including hooks in 
this thread, i.e. if it was possible to add a callback on a method, it would 
execute when it is called. I am not sure I understand your question.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/GD3TTQPULXGVQIKQUTERF6MAOD5WUS4B/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Steven D'Aprano
On Wed, Dec 09, 2020 at 12:05:17PM -, Mathew Elman wrote:
> Steven D'Aprano wrote:
> > On Tue, Dec 08, 2020 at 11:46:59AM -, Mathew Elman wrote:
> > > I would like to propose adding lazy types for casting
> > > builtins in a 
> > > lazy fashion. e.g. lazy_tuple which creates a reference to the 
> > > source iterable and a morally immutable sequence but only populates 
> > > the tupular container when it or the source is used.
> > > What are your use-cases for this?
> > Does this include things like lazy_list, lazy_float,
> > lazy_bool, 
> > lazy_str, lazy_bytearray etc?
> 
> I would say yes, it should include these types as well. 

> The use case is for when you are casting between types a high number 
> of times to pass them around, especially into another type and back.

I would say, *don't do that*. If you have a list, and you pass it to 
another function after converting to a tuple, why would you take that 
tuple and convert back to a list when you already have a list?

For types like casting back and forth between float and int, there will 
be data loss.

Even if there is not, the overhead of creating a "lazy proxy" to the 
float is probably greater than just converting.


> > How do these hooks freeze the list?
> 
> they don't freeze the list, they freeze the values in the lazy_tuple 
> when the list is mutated, so when mutating the list, the values in the 
> tuple are set (if they have not been already), so that they aren't 
> also mutated in the lazy_tuple.

How is this supposed to work in practice? Where does the hook live? When 
is it called? What does it do?

How does the lazy tuple know that the list's setitem has been called?


-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/AHVWVQZSC74R37ICARCHYIGBJTP54KCP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Joao S. O. Bueno
On Wed, 9 Dec 2020 at 09:27, Mathew Elman  wrote:

> I agree that if you are using them as iterables, then the type is usually
> not important because you are treating their type as just iter-able. The
> lazy iterable would more or less just be the same as passing in
> `iter(sequence)`.
>
> This is for other use cases where the use of the object is specific to the
> type, e.g. a case where in the outer scope you construct a list and mutate
> it but when it is passed to an inner scope, you want to enforce that it can
> be accessed but not mutated. Likewise if lazy built in types were
> implemented in python then getting a slice of a sequence could also be done
> lazily, whereas my understanding at the moment is that it has to create a
> whole new sequence.
>

If you need this for annotations/typing alone,
can't you just use `typing.cast` in the inner scope?
(or before calling it for that matter)

Anyway, mypy at least wil error if you annotate the inner scope as a
"Sequence" (in contrast with MutableSequence), and
will error if you try to change the Sequence - and it stlll remain
compatible with incoming "MutableSequences".
For the cases it does not cover, there is still "cast" - and it feels _a
lot_ simpler than having
actual runtime lazy objetcs as primitives in the language.

> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/ZQIXX5632QT7QH5YCZGTTLPJ5ZQF7XOH/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/IWY3I4ZTPT2ZV7XFMGGSGOWHT3UOXA53/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Mathew Elman
Stestagg wrote:
> That makes sense, so these are kind of 'views' over a sequence, but ones
> that implement a copy-on-write when the underlying object is modified in
> any way?

yes, a lazy sequence type would be exactly that, that is a nice way of putting 
it

> I can see this being super hard/impossible to implement reliably, but would
> be a pretty nice addition if it can be done.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/TI7KE4SLB3C2GHU3W2B6BOCL3ER3JLZO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Stestagg
That makes sense, so these are kind of 'views' over a sequence, but ones
that implement a copy-on-write when the underlying object is modified in
any way?

I can see this being super hard/impossible to implement reliably, but would
be a pretty nice addition if it can be done.

On Wed, Dec 9, 2020 at 12:25 PM Mathew Elman  wrote:

> I agree that if you are using them as iterables, then the type is usually
> not important because you are treating their type as just iter-able. The
> lazy iterable would more or less just be the same as passing in
> `iter(sequence)`.
>
> This is for other use cases where the use of the object is specific to the
> type, e.g. a case where in the outer scope you construct a list and mutate
> it but when it is passed to an inner scope, you want to enforce that it can
> be accessed but not mutated. Likewise if lazy built in types were
> implemented in python then getting a slice of a sequence could also be done
> lazily, whereas my understanding at the moment is that it has to create a
> whole new sequence.
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/ZQIXX5632QT7QH5YCZGTTLPJ5ZQF7XOH/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/LGXP6YBO5URDFJ7RIQ3OBFQ7MUQTDMWB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Mathew Elman
I agree that if you are using them as iterables, then the type is usually not 
important because you are treating their type as just iter-able. The lazy 
iterable would more or less just be the same as passing in `iter(sequence)`.

This is for other use cases where the use of the object is specific to the 
type, e.g. a case where in the outer scope you construct a list and mutate it 
but when it is passed to an inner scope, you want to enforce that it can be 
accessed but not mutated. Likewise if lazy built in types were implemented in 
python then getting a slice of a sequence could also be done lazily, whereas my 
understanding at the moment is that it has to create a whole new sequence.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ZQIXX5632QT7QH5YCZGTTLPJ5ZQF7XOH/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Stestagg
On Wed, Dec 9, 2020 at 12:05 PM Mathew Elman  wrote:

> Steven D'Aprano wrote:
> > On Tue, Dec 08, 2020 at 11:46:59AM -, Mathew Elman wrote:
> > > I would like to propose adding lazy types for casting
> > > builtins in a
> > > lazy fashion. e.g. lazy_tuple which creates a reference to the
> > > source iterable and a morally immutable sequence but only populates
> > > the tupular container when it or the source is used.
> > > What are your use-cases for this?
> > Does this include things like lazy_list, lazy_float,
> > lazy_bool,
> > lazy_str, lazy_bytearray etc?
>
> I would say yes, it should include these types as well.
> The use case is for when you are casting between types a high number of
> times to pass them around, especially into another type and back.
>
>
Out of morbid curiosity, why would you need to be casting between iterables
many times? Don't most consumers treat iterables roughly equally?
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/PYT3A5XMVJVT3PEAQ6RTFQUQKWQOSEHQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-09 Thread Mathew Elman
Steven D'Aprano wrote:
> On Tue, Dec 08, 2020 at 11:46:59AM -, Mathew Elman wrote:
> > I would like to propose adding lazy types for casting
> > builtins in a 
> > lazy fashion. e.g. lazy_tuple which creates a reference to the 
> > source iterable and a morally immutable sequence but only populates 
> > the tupular container when it or the source is used.
> > What are your use-cases for this?
> Does this include things like lazy_list, lazy_float,
> lazy_bool, 
> lazy_str, lazy_bytearray etc?

I would say yes, it should include these types as well. 
The use case is for when you are casting between types a high number of times 
to pass them around, especially into another type and back.

> > An alternative to adding lazy types / lazy type
> > casting (making it 
> > possible to implement these oneself) would be to add method call hooks 
> > to python, since this would allow having a "freeze value" callback 
> > hooked into the __setitem__ and __getitem__ methods.  Hooks may be a 
> > more useful solution for wider use cases as well.
> > Nope, sorry, I don't see how that would work. Here I have a list:
> L = [50, 40, 30, 20, 10]
> 
> Suppose these hooks exist. I want to make a "lazy tuple":
> t = lazy_tuple(L)
> 
> How do these hooks freeze the list?

they don't freeze the list, they freeze the values in the lazy_tuple when the 
list is mutated, so when mutating the list, the values in the tuple are set (if 
they have not been already), so that they aren't also mutated in the 
lazy_tuple. Of course for delete and insert this would mean you might have to 
"freeze" from where the insert/delete occurs to the end of the tuple but that 
is no different than using a normal tuple i.e. iterate over all elements. 
However for setitem where only position i is replaced, the tuple can set its 
value to the original without having to evaluate anything extra.

> What if I have more than one lazy object pointing at the same source?
> s = lazy_str(L)
> 
> And then follow with a different method call?
> L.insert(2, "surprise!")
> 
> I just can't see how this will work.

I don't follow what your point is, sorry. Are you saying that insert is another 
method that can update a list so delitem and setitem hooks would miss it?
The point I was making with hooks is that you _could_ write a lazy class that 
creates freezing hooks for any mutation method. But the hooks would be up to 
the coder to implement and hook into the correct mutation methods.

I also don't see an issue with multiple lazy types pointing to the same 
"source". It would just freeze the values in both of them when updating 
anything in the original.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YJ4GVP3KOB2WRU2EY3QO2XGNIFJAGZS2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-08 Thread Steven D'Aprano
On Tue, Dec 08, 2020 at 11:46:59AM -, Mathew Elman wrote:

> I would like to propose adding lazy types for casting builtins in a 
> lazy fashion. e.g. `lazy_tuple` which creates a reference to the 
> source iterable and a morally immutable sequence but only populates 
> the tupular container when it or the source is used.

What are your use-cases for this?

Does this include things like `lazy_list`, `lazy_float`, `lazy_bool`, 
`lazy_str`, `lazy_bytearray` etc?


> An alternative to adding lazy types / lazy type casting (making it 
> possible to implement these oneself) would be to add method call hooks 
> to python, since this would allow having a "freeze value" callback 
> hooked into the __setitem__ and __getitem__ methods.  Hooks may be a 
> more useful solution for wider use cases as well.

Nope, sorry, I don't see how that would work. Here I have a list:

L = [50, 40, 30, 20, 10]

Suppose these hooks exist. I want to make a "lazy tuple":

t = lazy_tuple(L)

How do these hooks freeze the list?

What if I have more than one lazy object pointing at the same source?

s = lazy_str(L)

And then follow with a different method call?

L.insert(2, "surprise!")

I just can't see how this will work.


-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6OLOHQBMYVPQSDAI5HRTRBVJRKDYB4QM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Lazy Type Casting

2020-12-08 Thread Paul Sokolovsky
Hello,

On Tue, 08 Dec 2020 11:46:59 -
"Mathew Elman"  wrote:

> I am not sure if this has been suggested before, so my apologies if
> it has.
> 
> I would like to propose adding lazy types for casting builtins in a
> lazy fashion. e.g. `lazy_tuple` which creates a reference to the
> source iterable and a morally immutable sequence but only populates
> the tupular container when it or the source is used.
> 
> Note that if the original object is not a built-in, will not be used
> after casting  _or_ is immutable, this is trivial to implement. The
> difficulty arises when this it not the case, since the lazy object
> needs to also freeze any values that are mutated in the original to
> avoid side-effects.

You pinpointed the problem exactly. So, the only reliable way to create
"lazy" version is to store a copy *eagerly*, which makes the point moot.

Lazy-evaluation languages usually deal with that problem by
disallowing mutation in the first place (i.e. being purely
functional). You can use that solution in Python too. (Without "no
mutation" error checking, but it should be possible to implement the
alternative API which is "immutable", and I bet someone even did
that (PoC-style of course).) 

> An alternative to adding lazy types / lazy type casting (making it
> possible to implement these oneself) would be to add method call
> hooks to python, since this would allow having a "freeze value"
> callback hooked into the __setitem__ and __getitem__ methods.  Hooks
> may be a more useful solution for wider use cases as well.

[]

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/MV4RZSAC3GK65SICBUIOMNNQDDFIK5MC/
Code of Conduct: http://python.org/psf/codeofconduct/