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

Alias Text and String to be the same #136

Closed
chrisdone opened this issue Oct 29, 2012 · 26 comments
Closed

Alias Text and String to be the same #136

chrisdone opened this issue Oct 29, 2012 · 26 comments

Comments

@chrisdone
Copy link
Contributor

When sharing datatypes between the server and client, I'm forced to use String instead of Text (there are likely a few other examples of this too). It would be nice if Fay could automatically treat Text as a synonym for String, while for the server-side code use Data.Text.Text.

@singpolyma
Copy link

Since Text is a packed representation, maybe Text should be a JavaScript string instead of a FayList ?

@chrisdone
Copy link
Contributor Author

This issue's in response to a correspondence with Snoyman:

Regarding Text, I kinda wanted to use the Text type to be an
abstract data type for native JS strings, but it's just a name.
Regardless, I think we can make Text an alias for String as far as Fay
is concerned, yeah. Made an issue for it:
#136

It's still debatable.

It may be that we should change all Fay's text functions (well, it doesn't have any… I'm really talking about libraries like the DOM or jQuery) to work on a packed Text type and not String. That way we keep the familiar name, Text and have slightly more efficient strings. Thoughts, everyone? I could go either way on this, I think.

@cdsmith
Copy link

cdsmith commented Oct 31, 2012

I think using Text is the right idea. It's already an abstract packed unicode type, while String exposes constructors, and it would be very messy to fake the existence of exposed constructors.

We should transparently replace Text if and only if we can maintain compatibility with a restricted subset of the API from Data.Text in the text package. In that case, when we build fay-base, we should have the GHC version depend on text as well as base (again, I'm hopeful we can support -XCPP to make this kind of thing work), and re-export the types from Text when it's built by GHC, but use the native JavaScript replacement otherwise. That way packages that are intended to be used with Fay would include fay-base in their Cabal Build-depends instead of text directly. When those packages are built with GHC, they will interoperate just fine with other packages built against text.

@chrisdone
Copy link
Contributor Author

Indeed, it has the same code sharing benefits. Also functions like scanl/unfoldr and such can be written in tight loops as they are in the actual Data.Text.

@snoyberg
Copy link
Contributor

snoyberg commented Dec 6, 2012

Sorry I'm coming late to this party.

I like the idea of Text being a packed representation (i.e., a JS String). But I don't think it's necessary to provide an API for manipulating a Text value, though it would be nice. For many use cases, simply being able to send raw textual values across the wire and insert them into the DOM is sufficient.

@snoyberg
Copy link
Contributor

snoyberg commented Jan 6, 2013

So I've started approaching the concept of Text. The first step is fairly simple: commit f76f7e8 makes it possible for the server to deserialize directly into Text. (Serializing already worked.)

The next step is what confuses me. I discussed this a bit with @ajnsit, and for our purposes, I believe we just need three new exports from Language.Fay.Prelude: Text, fromString, and toString, with the functions having the signatures String -> Text and Text -> String, respectively.

When using GHC, these three imports should just be Text, pack, and unpack from Data.Text. When compiling to JS, Text should be an abstract type, and I think the implementations of fromString and toString would just be Fay$$fayToJs and Fay$$jsToFay.

I'm uncertain of how to proceed about implementing this, however. I was thinking about creating two separate modules, one for GHC compilation, and one for Fay usage (I started playing around with this approach in our local codebase), but I'm not really sure how to proceed about implementing it. Any advice/suggestions would be appreciated.

snoyberg added a commit to fpco/fay that referenced this issue Jan 6, 2013
@chrisdone
Copy link
Contributor Author

I did a demo implementation in branch text here: 72ee26f That's one way to do it, so that Text is just treated as an alias for String underneath. I imagine you can fiddle with that as a base to get the kind of behaviour you're after? The example output was:

chris@midnight:~/Projects/me/fay$ dist/build/fay/fay examples/text.hs --no-ghc
chris@midnight:~/Projects/me/fay$ node examples/text.js
Hello!
Hello.
Hai!

@snoyberg
Copy link
Contributor

snoyberg commented Jan 6, 2013

Thank you, I'll have a look at that in more depth tomorrow to see how far I can take it. For comparison, I implemented basically what I needed for my current project in yesod-fay with the following commit: fpco/yesod-fay@c48723d . But it would be much better to have the functionality in Fay itself, I'll definitely take a stab at the implementation.

@cdsmith
Copy link

cdsmith commented Jan 6, 2013

My understanding is that String is currently defined as a list internally
(as it should be, given the subset-of-Haskell property), with automatic
conversion to and from JavaScript strings at the FFI boundary. We want
Text to be an opaque type that is always a JavaScript string, right? So if
by alias you meant type synonym, then I don't think that's the right way to
go.

Michael, I agree that you basically want two implementations of Text; the
GHC one should point at the text package, and the Fay one should implement
some subset of the Data.Text interface using JavaScript string manipulation
via the FFI. My hope is that we can support CPP to do this kind of
thing... but I haven't implemented it, and am unlikely to work on Fay again
for a few weeks.

GHC has a flag to do the CPP processing, so it's actually not hard... but
there's a question of what to do with --no-ghc. If that really means no
GHC, then we need an alternative implementation of the C preprocessor. If
it just means no GHC type checking, then we can invoke GHC for the
preprocessing anyway.

On Sun, Jan 6, 2013 at 9:44 AM, Michael Snoyman notifications@github.comwrote:

Thank you, I'll have a look at that in more depth tomorrow to see how far
I can take it. For comparison, I implemented basically what I needed for my
current project in yesod-fay with the following commit: fpco/yesod-fay@
c48723dhttps://github.com/fpco/yesod-fay/commit/c48723dd9c42729abc96f01c663fa4669de03782. But it would be much better to have the functionality in Fay itself, I'll
definitely take a stab at the implementation.


Reply to this email directly or view it on GitHubhttps://github.com//issues/136#issuecomment-11931381.

@bergmark
Copy link
Member

bergmark commented Jan 6, 2013

Afaik --no-ghc just means "no typechecking", i think it's safe to assume that ghc is available for other things

@snoyberg
Copy link
Contributor

snoyberg commented Jan 7, 2013

My hope is that we can support CPP to do this kind of
thing... but I haven't implemented it, and am unlikely to work on Fay again
for a few weeks.

If you look at the yesod-fay code I referenced, I actually implemented a minimal subset of CPP necessary in order to switch between Fay and GHC code. It's not beautiful, but I think it's sufficient for our purposes here. Any objection if I end up using something like that in my implementation?

We could also consider using cpphs, but (1) I think it's a bit overkill, and (2) the licensing scares me.

@singpolyma
Copy link

I think in general platforms will have a cpp or similar hanging around for use, I believe with standard cpp the switches needed are -C -P

@snoyberg
Copy link
Contributor

snoyberg commented Jan 7, 2013

But do we really want to have to spin off a separate process each and every time we compile a file? Basic support for #ifndef FAY seems like all we'll need for the foreseeable future. And if we discover we need something more powerful later, we can either (1) write soemthing more powerful, or (2) introduce the cpp dep then.

Additionally, I wouldn't want to unnecessarily tie ourselves to specific run environments. Wasn't there a proof-of-concept Fay-compiled-to-JS-via-GHCJS? Such a technique couldn't be implemented if we depended on cpp for basic functionality.

@bergmark
Copy link
Member

bergmark commented Jan 7, 2013

I think I would prefer to use either @snoyberg's custom CPP code or cpphs over cpp. @snoyberg it sounds like it would be simpler/quicker to start with your code then? And if we end up wanting cpphs for some reason, are there any problems with us linking to LGPL? I think it's fine, IANAL :)

@snoyberg
Copy link
Contributor

snoyberg commented Jan 7, 2013

@bergmark Yes, I think using my CPP code will be fastest to getting started. IANAL, but LGPL does worry me (though cpphs also has some custom license as well). But it doesn't really matter: if cpphs is viral, then fay is already infected: http://packdeps.haskellers.com/licenses/fay

@singpolyma
Copy link

Somebody claiming to be Michael Snoyman wrote:

IANAL, but LGPL does worry me (though cpphs also has some custom license
as well).

IANAL, but the LGPL is not going to "viral" you for exec'ing it. Even the
GPL will not (according to any current enforcer or interpretation that
I have read on the suject).

Stephen Paul Weber, @singpolyma
See http://singpolyma.net for how I prefer to be contacted
edition right joseph

@snoyberg
Copy link
Contributor

snoyberg commented Jan 7, 2013

I link against fay, and therefore against cpphs.

@cdsmith
Copy link

cdsmith commented Jan 7, 2013

Yep, and that's via haskell-src-exts, which is not going to go away.

Makes me wonder, though... does haskell-src-exts already support CPP?

On Mon, Jan 7, 2013 at 7:45 AM, Michael Snoyman notifications@github.comwrote:

@bergmark https://github.com/bergmark Yes, I think using my CPP code
will be fastest to getting started. IANAL, but LGPL does worry me
(though cpphs also has some custom license as well). But it doesn't really
matter: if cpphs is viral, then fay is already infected:
http://packdeps.haskellers.com/licenses/fay


Reply to this email directly or view it on GitHubhttps://github.com//issues/136#issuecomment-11956330.

@cdsmith
Copy link

cdsmith commented Jan 7, 2013

And the answer: no, it's just used for unlit currently.

On Mon, Jan 7, 2013 at 8:33 AM, Chris Smith cdsmith@gmail.com wrote:

Yep, and that's via haskell-src-exts, which is not going to go away.

Makes me wonder, though... does haskell-src-exts already support CPP?

On Mon, Jan 7, 2013 at 7:45 AM, Michael Snoyman notifications@github.comwrote:

@bergmark https://github.com/bergmark Yes, I think using my CPP code
will be fastest to getting started. IANAL, but LGPL does worry me
(though cpphs also has some custom license as well). But it doesn't really
matter: if cpphs is viral, then fay is already infected:
http://packdeps.haskellers.com/licenses/fay


Reply to this email directly or view it on GitHubhttps://github.com//issues/136#issuecomment-11956330.

snoyberg added a commit to fpco/fay that referenced this issue Jan 7, 2013
chrisdone pushed a commit that referenced this issue Jan 7, 2013
@chrisdone
Copy link
Contributor Author

I'm starting work on fay-base as described in #139. I think fay-text should be the same:

When building for the client, you would use fay -package text (but that would refer to fay-text—given that Fay packages require a specific format, it's okay to have this convenient prefix omission.). When building for the server, you would use ghc -package text.

I don't quite see where the CPP enters into it.

@cdsmith
Copy link

cdsmith commented Jan 8, 2013

Well, CPP was there as a way to get Fay and Haskell code to build using the
same packages. Your approach is to have them use different packages. That
works, too, I suppose.

On Mon, Jan 7, 2013 at 1:15 PM, Chris Done notifications@github.com wrote:

I'm starting work on fay-base as described in #139#139.
I think fay-text should be the same:

When building for the client, you would use fay -package text (but that
would refer to fay-text—given that Fay packages require a specific
format, it's okay to have this convenient prefix omission.). When building
for the server, you would use ghc -package text.

I don't quite see where the CPP enters into it.


Reply to this email directly or view it on GitHubhttps://github.com//issues/136#issuecomment-11972057.

@bergmark
Copy link
Member

bergmark commented Feb 8, 2013

Should be possible to do this now! I guess we can just have an opaque type Text around js strings, or is there still a need to alias this with String? Seems reasonable to me to provide separate implementations since that's what Haskell does.

@cdsmith
Copy link

cdsmith commented Feb 8, 2013

I definitely agree with keeping them separate, and providing an API for
Text that's a subset of Data.Text.
On Feb 8, 2013 2:02 PM, "Adam Bergmark" notifications@github.com wrote:

Should be possible to do this now! I guess we can just have an opaque type
Text around js strings, or is there still a need to alias this with String?
Seems reasonable to me to provide separate implementations since that's
what Haskell does.


Reply to this email directly or view it on GitHubhttps://github.com//issues/136#issuecomment-13314440..

@bergmark
Copy link
Member

Here's a very nice solution for this! #321
We can keep String as the default, but allow Text literals on a module basis without breaking any existing code.

@bergmark
Copy link
Member

Related to this I'll try to (finally) release fay-text this week adding Text manipulation functions to it as well.
@snoyberg I started from the Fay.Text module in yesod-fay that you wrote, so I added you as an author. I plan to maintain it myself unless you have other preferences. Here's the package: https://github.com/faylang/fay-text

@snoyberg
Copy link
Contributor

@bergmark This looks like good stuff, I'm happy to see this package come into existence!

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

5 participants