evhub / coconut

Simple, elegant, Pythonic functional programming.
http://coconut-lang.org
Apache License 2.0
4.09k stars 125 forks source link

Backport python 3.7 dataclass #376

Open dileep-kishore opened 6 years ago

dileep-kishore commented 6 years ago

A new dataclass decorator was recently accepted into python 3.7 (https://www.python.org/dev/peps/pep-0557/).

The implementation seems similar to coconut's implementation of the data type (subclassing the namedtuple) but they differ in terms of their syntax. I was just wondering whether coconut would keep the current syntax (for backward compatibility) or would it be changing to the new syntax (to avoid feature duplication). I just asked this question because I'm curious.

evhub commented 6 years ago

@dileep-kishore The problem with dataclass from a functional standpoint is that data classes are mutable. Coconut's data types, on the other hand, are immutable. That's very important if you're doing functional programming, so dataclass won't be replacing Coconut's data types.

dileep-kishore commented 6 years ago

@evhub you're right. I assumed they inherited from namedtuples but it looks like they just create normal classes.

benji-york commented 6 years ago

The dataclass decorator accepts a "freeze" argument which makes the instances read-only (well, as read-only as anything gets in Python).

On Fri, Dec 8, 2017 at 3:27 PM, Dileep Kishore notifications@github.com wrote:

@evhub https://github.com/evhub you're right. I assumed they inherited from namedtuples but it looks like they just create normal classes.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/evhub/coconut/issues/376#issuecomment-350376198, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAkrw92l2B-HryokOOuaZNCODXzhnbfks5s-amkgaJpZM4Q7lbY .

-- Benji York

evhub commented 6 years ago

@benji-york Really? I didn't know that. I don't see it in the PEP, though--where's the source for that?

evhub commented 6 years ago

Though dataclass won't be replacing data, I think it would be really nice to have Coconut port dataclass to work on any Python version, so I'm going to reopen this issue with that in mind.

dileep-kishore commented 6 years ago

@evhub This is what it says:

"frozen: If true (the default is False), assigning to fields will generate an exception. This emulates read-only frozen instances."

evhub commented 6 years ago

@dileep-kishore Ah, I see. Yeah, I'd definitely like to use Coconut to port dataclass to older Python versions, though I still won't be removing data, since there are still things like data Tuple(*args) that can't be done with dataclass.

Hong-Xiang commented 5 years ago

For older versions of Python, we can get same functionality of dataclasses via attrs, as this says, it support PyPi, Python 2.7, 3.4+.

It supports

@attr.s(auto_attribs=True) class vector20: x: int y: int

@attr.s(auto_attribs=True) class vector21: x: int y: int

print(vector20(0, 1) == vector20(0, 1)) # return True print(vector20(0, 1) == vector21(0, 1)) # return False

and lots of other features.

I'm wondering if it is allowed to add this package as dependency of coconut?

If it is allowed, I'm wondering how to learn about the compiling process of `data`. I've found `data_handle` in L1202 of `compiler/compiler.py`, and it seems that for basic `data` support, only block after L1331 `elif saw_defaults:` should be modified, but there I'm confused of matching `simple`, `docstring`, e.t.c in `stmts`. How to learn this block of code? I can't add break point to compiler, and adding `print` statement seems not work.

On the other hand, May data support annotations from [PEP 526]? Thus like

data vector2: x: int = 0 y: int = 0

majidaldo commented 2 years ago

Q: is it possible to have different compilation 'backends' for 'data'? like dataclass(frozen=True) or attr.s(frozen=True)? They have a good amount of ecosystem support and utilities.

evhub commented 2 years ago

@majidaldo What sort of ecosystem support are you referring to? Can you provide an example of a situation where an attr/dataclass-based data would be able to do something that a namedtuple-based data wouldn't?

majidaldo commented 2 years ago

@majidaldo What sort of ecosystem support are you referring to? Can you provide an example of a situation where an attr/dataclass-based data would be able to do something that a namedtuple-based data wouldn't?

auto serialization, evolution, conversion.

A user could probably implement these in coconut code. But, it would be nice to be able to (declaratively) create a 'schema' in Python which can serve as an interop b/w coconut and python. coconut would just need to add fmap (?).

evhub commented 2 years ago

serialization, evolution, conversion

@majidaldo .asdict() is already available as ._asdict(). Field transformation is possible via pattern-matching (see below) or writing a __new__ and updating is possible via ._replace. cattrs support is the one thing there I'm not sure if data types can do, since it seems like cattrs might not support namedtuples—if there's something Coconut can do to give data types cattrs support, I'd definitely be willing to look into it. My guess is that's probably more on the cattrs end, though—all they should need to do is support namedtuples, though.

Here's field transformation via pattern-matching, btw:

>>> data lenient_2vec(int -> x, int -> y)
>>> lenient_2vec("1", 2.5)
lenient_2vec(x=1, y=2)
majidaldo commented 2 years ago

serialization, evolution, conversion

@majidaldo .asdict() is already available as ._asdict(). Field transformation is possible via pattern-matching (see below) or writing a __new__ and updating is possible via ._replace. cattrs support is the one thing there I'm not sure if data types can do, since it seems like cattrs might not support namedtuples—if there's something Coconut can do to give data types cattrs support, I'd definitely be willing to look into it. My guess is that's probably more on the cattrs end, though—all they should need to do is support namedtuples, though.

Here's field transformation via pattern-matching, btw:

>>> data lenient_2vec(int -> x, int -> y)
>>> lenient_2vec("1", 2.5)
lenient_2vec(x=1, y=2)

._asdict() isn't recursive though. an effect that i've been able to achieve with attrs is to fully define a data structure for my programs that represent state that can be programmatically 'lifted' and 'exported' to whatever...structure intact.

majidaldo commented 2 years ago

more comprehensively https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs. on another note, attrs just completely solves what you might want out of dataclasses.

evhub commented 2 years ago

on another note, attrs just completely solves what you might want out of dataclasses.

@majidaldo Perhaps the better question, then, since you can just import attrs in Coconut, is what features from data types you would like to be available when using attrs.