Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions/Notes #2

Open
DNEAVES opened this issue Sep 24, 2024 · 3 comments
Open

Questions/Notes #2

DNEAVES opened this issue Sep 24, 2024 · 3 comments

Comments

@DNEAVES
Copy link

DNEAVES commented Sep 24, 2024

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
Copy link
Owner

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

  • Pretty sure callable will work fine there. I don't remember why I was thinking it would make sense to attach it as a method. They would only ever be defined in a constructor as a callback, so would need to be unique per instance.
  • In general python's lambda doesn't map to Gleam functions because lambda is a single-line expression. Right now macabre always creates a new named function (with a generated name) and uses that name at the callsite. It would be possible to check whether or not a gleam function body can compile down to a single python expression and use lambda if it does, but I'm nowhere near those kinds of optimizations.
  • TBH, the only thing I know about HoleType is that it is defined in the glance parser as a top-level type: https://hexdocs.pm/glance/glance.html#Type I haven't taken the time to dig into the gleam compiler to figure out what kind of syntax generates that type. The only reference in macabre is here: https://github.com/dusty-phillips/macabre/blob/main/src/compiler/internal/transformer/types.gleam#L49 (In general, if we can remove every todo in the codebase, we have a hard guarantee that we covered every piece of syntax Glance can parse)
  • 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.
  • Slightly related: I've daydreamed about porting gleam-otp to python 3.13 compiled without the gil. That would allow me to support parallel compilation and be a key step towards efficient self-hosting.
  • Last note: My most recent work on this project has been happening in the https://github.com/dusty-phillips/glimpse package where I tried my hand at writing a typechecker without studying type theory. 😅 I got the basics in place but it doesn't cover nearly as much syntax as macabre yet so I can't depend on it.

@DNEAVES
Copy link
Author

DNEAVES commented Sep 25, 2024

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
Copy link
Owner

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants