dusty-phillips / macabre

experimental and slightly-functional gleam-to-python transpiler
Apache License 2.0
3 stars 1 forks source link

Questions/Notes #2

Open DNEAVES opened 1 month ago

DNEAVES commented 1 month ago

Hey there! This project seems neat, and I would like to contribute.

I have a note and two questions for now on the Priorities listed:

Functions as type fields are not supported yet e.g pub type Foo {Foo(x: () -> String)} debatable whether to make them a def right on the class or have the def be defined somewhere and just attach it like other fields

This should be possible as a typing.Callable field, just need to generate one of these:

from dataclasses import dataclass
from typing import Callable

# here as an example for a def func. lambda example below.
def custom_add(a: int, b: int) -> int:
    return a + b

@dataclass
class Test:
    some_def: Callable[[int, int], int] = custom_add
    some_lambda: Callable[[int, int], int] = lambda x, y: x + y

Perhaps for whether it's a def or a lambda, follow the convention that's used in the Gleam code: pub function if named/defined, lambda if anonymous. Of course, a major downside for the lambda approach is that you can't annotate types on it directly, but at least the dataclass field's Callable annotation should have that covered.

Fields that are "HoleType" are not supported and I don't even know what that means

Is this meant like a catch-all type? Or a variable-type annotation like foo :: a -> a? Or something along the lines of a Typed-Hole? Maybe context around where this came from might help in figuring out what (if anything) needs be done.

Last, is there anything in place right now to determine the python version being targeted, or is it only targeting one version at the moment? (Like if 3.12 is being generated, the generated code could use the new type keyword syntax, but 3.11 would have to rely on typing.TypeAlias)

dusty-phillips commented 1 month ago

Hi, thanks for your interest! Would be fun to have someone to join me in this craziness. :) These are good points and questions.

DNEAVES commented 1 month ago

TBH, the only thing I know about HoleType is that it is defined in the glance parser as a top-level type

Seems like HoleType is the result of a DiscardName(String), which I'd assume is a leading-underscore variable name like _this = "some garbage", or maybe even just an underscore like _ = 0. In the generated Python, this should be equivalent (except that Python just treats them as regular variables, sans solo-underscore, and it's up to the developers to know not to use it)

I haven't thought about a minimum version target, but I think targeting 3.12 is safe. Anyone who uses this project before 3.11 is EOL is by nature an early adopter anyway! The lower bound is currently 3.10 because we use match.

3.12 is fine with me, just wanted to know the targeted version so I know what syntax and feature stuff to work with. I figured at least 3.10 since I saw a use of match-case.

Perhaps eventually, the configuration toml can contain a field for a target Python version, but then multiple generators may need to exist for the slight differences between version, unless its decided to just ignore new syntax stuff (like ignoring 3.12's type declaration and use typing.TypeAlias).

dusty-phillips commented 1 month ago

I had a feeling it might be related to discards, but I couldn't figure out why it would be necessary. Turns out it's because I punted on types. The current generated Python doesn't have type function arguments, so discards are just a variable with a _ prefix that isn't used in the body.

Once we get to typing functions it would probably need to be typing.Any (unless there is some kind of typing.Ignored that I'm not aware of).