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

Section syntax #1

Open
nikita-volkov opened this issue Jan 19, 2015 · 7 comments
Open

Section syntax #1

nikita-volkov opened this issue Jan 19, 2015 · 7 comments

Comments

@nikita-volkov
Copy link
Owner

Problem

How would this work with Applicative notation, like

parsePerson = Person <$> parseName <*> parseAge

Proposal

Unquote an expression of the following form

[r| {name, age} |]

to

\name age -> Record2 age name :: name -> age -> Record2 "age" age "name" name

(Note the reordering of arguments).

Then it will be possible to use it like this:

[r| {name, age} |] <$> parseName <*> parseAge

Extras

This can be extended even further to allow to partially initialize the record. E.g.:

[r| {name, age = 23} |] <$> parseName

Credits for the initial proposal go to a Reddit user htebalaka. Thank you!

@htebalaka
Copy link

It occurred to me that if you wanted to support NamedFieldPuns then the syntax is ambiguous in expressions. {a, b = 3} could be the function \a_1 -> {a = a_1, b = 3} or the record {a = a, b = 3} for whatever identifier a is in scope. You could disambiguate with a different quasiquoter I suppose, or a very slightly different syntax if you want something to can be supported unambiguously without a quasiquoter.

@nikita-volkov
Copy link
Owner Author

Hmm... Getting trickier. We'll need to research on the subject.

You could disambiguate with a different quasiquoter I suppose.

I'd much rather avoid a quasi-quoter-based logic. We should develop a syntax which we would not have to change in case at some point we implement a preprocessor, or hopefully implement a GHC syntax extension.

@htebalaka
Copy link

I kind of assumed that was the goal. I thought it'd be nice to be able to postprocess the generated function (for newtypes mainly, but also for functions like foo :: {a :: Int , b :: Int , c :: Int} -> IO (). If you had something like {<expr>\b, c=3, a} ==> \x y -> <expr> {b=x, c=3, a=y}, which could be used to convert anything expecting a record to a function with positional arguments in any order, without needing a lambda. Then if you had {\b, c=3, a} as shorthand for {id\b, c=3, a} you could disambiguate nicely even in the non-postprocessed case.

Then the syntax without the backslash character would indicate a record pattern/expression, and I think would handle both RecordWildCards and NamedFieldPuns cleanly.

EDIT: I guess full expressions wouldn't work that nicely, since {\x -> x^2\a} ==> \b -> (\x -> x^2) {a = b} would look kind of bad, though just an identifier to the left of the \ would probably handle the important use cases. Granted, even ignoring the postprocessing case, {\a,b} looks pretty nice to me to represent an anonymous function that returns a record.

@nikita-volkov
Copy link
Owner Author

Wait a second. I just realised that NamedFieldPuns is about a pattern context. This proposal concerns an expression context. We can have both things interpret the same syntax!

@htebalaka
Copy link

They apply to both unfortunately. In an expression let a = 1 in {a} ==> let a = 1 in {a = a}

@nikita-volkov
Copy link
Owner Author

Oh..

@htebalaka
Copy link

Another option would be something like {\d,\a,c=3,b}, if you wanted to be able to use NamedFieldPuns and lambdas together (to desugar to \x y -> {a=y, b=b, c=3, d=x} for whatever b is in scope.

Though NamedFieldPuns in an expression might cause issues in general; assuming the lenses are in scope and have the same name as the field then barring a special compiler rule for FieldOwner {a,b} could try to parse like {a=lens (Field :: Field "a"), b=lens (Field :: Field "b")} if a and b weren't being shadowed.

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