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

Reimplementation of morganey's quasiqotes #345

Open
keddelzz opened this issue Apr 16, 2017 · 8 comments
Open

Reimplementation of morganey's quasiqotes #345

keddelzz opened this issue Apr 16, 2017 · 8 comments

Comments

@keddelzz
Copy link
Collaborator

keddelzz commented Apr 16, 2017

I suggest to add another feature to morganey's quasiquotation.

Current situation

The current implementation of the quasiquotes allows some nice operarations on LambdaTerms.

  • putting terms into other terms
val term1 = m"42"
val term2 = m"$term1 5"
  • putting scala values into terms and let them automatically be converted to LambdaTerms.
val v1 = "Hello, "
val v2 = "World!"

val term = m"(append $v1 $v2)"
  • extracting terms from other terms
val term1 = m"(42 42)"
val m"($twentyFour 42)" = term1
// use `twentyFour`
// twentyFour :: LambdaTerm
  • extracting values from other terms and let them automatically be converted to the specified scala type
val term1 = m"(42 42)"
val m"(${twentyFour: Int} 42)" = term1
// use `twentyFour`
// twentyFour :: Int

New feature

  • At the moment you can't put an arbitrary amount of terms into other terms
val list = List(m"1", m"2", m"3") // :: List[LambdaTerm]
val term = m"[..$list]"
// `term` is a morganey-list containing 1, 2 and 3
val list = List('H', 'e', 'y') // :: List[Char]
val term = m"[..$list]"
// `term` is a morganey-list containing '1', '2' and '3'

The .. in the quasiquote allows to spread the contents of a scala-list into lists (as shown in the example above).

@keddelzz
Copy link
Collaborator Author

keddelzz commented Apr 16, 2017

I have already toyed with the implementation of the feature. The (unfinished) results can be seen in this commit.

Even if this issue gets rejected, I had a lot of fun implementing this (unfinished) feature :)

Todos

  • Are there additional places (other than lists) where spreading multiple values/terms is reasonable?
  • Unlifting and unsplicing LambdaTerms
val m"['H', 'e', 'l', 'l', 'o', ..${nameLetters: List[Char]}]" = m""" "Hello, Morganey" """
// `nameLetters` = List('M', 'o', 'r', 'g', 'a', 'n', 'e', 'y', '!')

@rexim
Copy link
Member

rexim commented Apr 17, 2017

@keddelzz thank you very much for the proposal! I'll take a look into it a little bit later.

@keddelzz
Copy link
Collaborator Author

Yesterday the quotation only worked in expression position. Now it works in pattern position as well (see Todo Unlifting and unsplicing LambdaTerms above).

To see the changes you can look at this commit.

Please note, that I haven't extensively tested the code. There will be bugs. I will test the code if I find the time.

@rexim
Copy link
Member

rexim commented Apr 18, 2017

  1. To make the process of code review easier for everyone you could've created a Pull Request — the mechanism developed by GitHub team specificly for that.

  2. I believe there is a mistake in this comment:

val list = List('H', 'e', 'y') // :: List[Char]
val term = m"[..$list]"
// `term` is a morganey-list containing 1, 2 and 3

It should contains list of characters, not numbers.

  1. I don't understand why do we need this feature. Couldn't we just
val list = List(1, 2, 3)
val term = m"$list"

and get the Morganey list of numbers before? Is there anything we cannot perform using the current capabilities of quasiquotation?

@keddelzz
Copy link
Collaborator Author

keddelzz commented Apr 18, 2017

To make the process of code review easier for everyone you could've created a Pull Request — the mechanism developed by GitHub team specificly for that.

Thank you for the reminder, I will create a PR now!

I believe there is a mistake in this comment

Fixed! Thanks for spotting that!

Is there anything we cannot perform using the current capabilities of quasiquotation?

Yes, there is! We cannot

  • extract the start of a list and match against a fixed rest
val m"[..$head, 6, 7, 8]" = m"[1 .. 8]"
  • extract the rest of a list and match against a fixed start
val m"[1, 2, 3, ..$tail]" = m"[1 .. 8]"
  • do one of the above and let the numbers be automatically converted to the specified type.
val m"['H', 'e', 'l', 'l', 'o', ',', ' ', ..${name: String}]" = m""" "Hello, Morganey"  """
println(name)  // > Morganey

or

val m"['H', 'e', 'l', 'l', 'o', ',', ' ', ..${name: Vector[Int]}]" = m""" "Hello, Morganey"  """
println(name)  // > Vector(77, 111, 114, 103, 97, 110, 101, 121)

All in all the new implementation lets us manipulate lists more easily.


We also cannot easily create nested applications and nested lambda functions using the quotation mechanism (This was meant by the first Todo above: Are there additional places (other than lists) where spreading multiple values/terms is reasonable?). To be fair, we can't currently do that in the new implementation, but the groundwork was done to be able to do so.

keddelzz added a commit that referenced this issue Apr 18, 2017
I created too huge patterns to be matched against. Those crashed the
compiler.
This change optimizes the pattern (and the runtime const) of huge
constants (numbers and characters) and other terms, whose representation
is very large (int-lists and char-lists/strings).
keddelzz added a commit that referenced this issue Apr 18, 2017
I created too huge patterns to be matched against. Those crashed the
compiler.
This change optimizes the pattern (and the runtime const) of huge
constants (numbers and characters) and other terms, whose representation
is very large (int-lists and char-lists/strings).
@rexim
Copy link
Member

rexim commented Apr 19, 2017

Why can't we just do all of those list manipulations in Scala after converting Morganey lists to Scala lists?

@keddelzz
Copy link
Collaborator Author

Of course we're able to do so, but it gets quite tedious, if you've to do those things often.

@rexim
Copy link
Member

rexim commented Apr 20, 2017

@keddelzz ok, I'll take a look at the code a little bit later. Thanks!

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

No branches or pull requests

2 participants