|
On Tue, Apr 24, 2012 at 9:26 AM, Yitzchak Gale <[hidden email]> wrote:
> Greg Weber wrote: >> I very much agree with you. However, when we complain about something >> essentially we are asking others to prioritize it ahead of other >> things. I don't think any more visibility of this issue is going to >> improve its prioritization. I suspect your only way forward right now >> is to start implementing something yourself. > > You're right. But as a professional Haskell developer, I am > under the same kinds of deadline pressures as any other > professional. So I'm afraid it's not going to be me, at least > not in the near future. > > However, what I can do is raise the red flag. Some people > are pushing things in directions which would cause > OverloadStrings to become more and more ubiquitous, > perhaps even the default. I want to make sure that the > people who are doing that are aware of the deep problems > with that approach. > > Sure, as much as anyone else, I want string literals > that can be typed as Text. But not at the cost of > delaying syntax checking to run time. > > And, as Bas points out, that there are many different > compile time mechanisms that could be used for this. > > Thanks, > Yitz Here's a theoretically simple solution to the problem. How about adding a new method to the IsString typeclass: isValidString :: String -> Bool We can give it a default implementation of `const True` for backwards compatibility. Then, whenever GHC applies OverloadedStrings in a case where the type is fully known at compile time (likely the most common case), it can run the check and- if it returns False- stop the compile. This has the benefits of letting existing code continue to work unchanged, and not requiring any Template Haskell to be involved. A downside is that it will still let invalid code through sometimes. Perhaps a solution is to modified the OverloadedStrings extension that requires that the type be fully known. If someone *really* wants polymorphic strings, they can explicitly add `fromString`. I actually think I'd prefer this version. Michael _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by J. Garrett Morris-3
J. Garrett Morris wrote:
> By this logic, head is "unsound", since head [] throws an error. > Haskell types are pointed; Haskell computations can diverge. Well, there are those who would actually agree with that and banish 'head' and friends from the language. But I'll agree with you here. [As an aside - I'm finding that liberal use of Edward's non-empty list type, found in the semigroups package, solves many of those problems for me.] But there are two crucial differences. First, head is just a partial function, not basic language syntax. Second, the divergence of head is constant and well-known, and not dependent on the implementation of a type class at particular types by various library authors. > What happens after the computation diverges is > irrelevant to type soundness. Agreed. I'm not talking about type soundness, in the technical sense. I'm talking about engineering soundness. Thanks, Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Michael Snoyman
Michael Snoyman wrote:
> Here's a theoretically simple solution to the problem. How about > adding a new method to the IsString typeclass: > isValidString :: String -> Bool > ...whenever GHC applies OverloadedStrings in a case > where the type is fully known at compile time (likely the most common > case), it can run the check and- if it returns False- stop the > compile. This approach does address the real reason that OverloadedStrings is unsafe in practice: library authors sometimes feel that they must reject certain strings. This gives them a safer outlet for that, with a nice simple API. However, it requires GHC to be able to resolve the monomorphic type of the string literal at a time when it can get its hands on the appropriate isValidString method, already compiled, and call it. Seems like in GHC, at least, the implementation of that would have to involve some kind of TH magic in the background. Is this possible? Thanks, Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
On Tue, Apr 24, 2012 at 9:26 AM, Yitzchak Gale <[hidden email]> wrote:
> However, what I can do is raise the red flag. Some people > are pushing things in directions which would cause > OverloadStrings to become more and more ubiquitous, > perhaps even the default. I want to make sure that the > people who are doing that are aware of the deep problems > with that approach. > > Sure, as much as anyone else, I want string literals > that can be typed as Text. But not at the cost of > delaying syntax checking to run time. What can go wrong when you use an overloaded string to be fromString'd into Text? -- Markus Läll _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
Markus Läll wrote:
> What can go wrong when you use an overloaded string to be fromString'd > into Text? Here's an example: The author of the xml-types package provides an IsString instance for XML names, so you can conveniently represent XML names as string literals in your source code. But not every string is a valid XML name. If you mistype the literal, your program will still compile. It may even run for a while. But when someone uses your program in a way that causes that mistyped XML name literal to be resolved, your program will likely crash, unless you structured it in a way that allows that XML name literal to be wrapped in an appropriate exception handler in the IO monad. -Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
I'm not following the details of this thread, but if you guys can come to a conclusion and write up a design, I'd be happy to discuss it.
If you want validation of literal strings, then TH quasiquotes are the way to go: [url| http://this/that |] will let you specify the parser/validator to use ("url" in this case) and allow any error messages to be delivered in a civilised way at compile time. I don't really want to make "http://this/that" have exactly this semantics; apart from anything else, which parser do you mean. This is what TH quasiquotation is *for*. Simon | -----Original Message----- | From: [hidden email] [mailto:glasgow-haskell- | [hidden email]] On Behalf Of Yitzchak Gale | Sent: 24 April 2012 07:46 | To: J. Garrett Morris | Cc: GHC users | Subject: Re: default instance for IsString | | J. Garrett Morris wrote: | > By this logic, head is "unsound", since head [] throws an error. | > Haskell types are pointed; Haskell computations can diverge. | | Well, there are those who would actually agree with that and banish 'head' | and friends from the language. | But I'll agree with you here. | | [As an aside - I'm finding that liberal use of Edward's non-empty list type, | found in the semigroups package, solves many of those problems for me.] | | But there are two crucial differences. First, head is just a partial | function, not basic language syntax. | Second, the divergence of head is constant and well-known, and not dependent | on the implementation of a type class at particular types by various library | authors. | | > What happens after the computation diverges is irrelevant to type | > soundness. | | Agreed. I'm not talking about type soundness, in the technical sense. I'm | talking about engineering soundness. | | Thanks, | Yitz | | _______________________________________________ | Glasgow-haskell-users mailing list | [hidden email] | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
I see what you mean -- many libraries provide conveniences like that
(like TagSoups `takeWhile (~== "</a>") tags' and so on). But that's the inherent mismatch between a String-- a unicode literal --and whatever else you want it to be, be it ASCII or bash or XML or something else.. I think the answer to them all is to use TH (as already suggested :-). A similar issue is printf, which handles the errors at runtime (though I think there's a TH solution already existing for that). On Tue, Apr 24, 2012 at 10:58 AM, Yitzchak Gale <[hidden email]> wrote: > Markus Läll wrote: >> What can go wrong when you use an overloaded string to be fromString'd >> into Text? > > Here's an example: > > The author of the xml-types package provides an IsString > instance for XML names, so you can conveniently > represent XML names as string literals in your source > code. > > But not every string is a valid XML name. If you mistype > the literal, your program will still compile. It may even run > for a while. But when someone uses your program in > a way that causes that mistyped XML name literal > to be resolved, your program will likely crash, unless you > structured it in a way that allows that XML name literal > to be wrapped in an appropriate exception handler in the > IO monad. > > -Yitz -- Markus Läll _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Michael Snoyman
On Tue, Apr 24, 2012 at 08:32, Michael Snoyman <[hidden email]> wrote:
> Here's a theoretically simple solution to the problem. How about > adding a new method to the IsString typeclass: > > isValidString :: String -> Bool If you're going with this approach, why not evaluate the conversion from String immediately? For either case you have to know the monomorphic type, and converting at compile time is more efficient as well. But we're getting pretty close to Template Haskell here. Erik _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Simon Peyton-Jones
Simon Peyton-Jones wrote:
> If you want validation of literal strings, then TH quasiquotes are the way to go: I agree. OverloadedStrings is, in effect, an unsafe replacement for quasiquotes. People find OverloadedStrings easier to use than quasiquotes, so its use in that way is becoming popular. What we need is a mechanism for allowing string literals to have the type Text or ByteString instead of String. I do not want to be forced to turn on UnsafeQuasiQuotes every time I need a string literal. So in my opinion, OverloadedStrings is the wrong mechanism for providing Text and ByteString literals. Alternatives that have been suggested: o A hard-coded pragma to specify the type of string literals in a module as Text or ByteString. o An extra method of IsString, of type QuasiQuoter, that runs at compile time in a monomorphic context. o As above, but only check syntax at compile time in a monomorphic context. That allows a simpler API, without requiring any TH knowledge in most cases. Thanks, Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Erik Hesselink
On Tue, Apr 24, 2012 at 11:36 AM, Erik Hesselink <[hidden email]> wrote:
> On Tue, Apr 24, 2012 at 08:32, Michael Snoyman <[hidden email]> wrote: >> Here's a theoretically simple solution to the problem. How about >> adding a new method to the IsString typeclass: >> >> isValidString :: String -> Bool > > If you're going with this approach, why not evaluate the conversion > from String immediately? For either case you have to know the > monomorphic type, and converting at compile time is more efficient as > well. But we're getting pretty close to Template Haskell here. > > Erik I could be mistaken, but I think that would be much harder to implement at the GHC level. GHC would then be responsible for taking a compile-time value and having it available at runtime (i.e., lifting in TH parlance). Of course, I'm no expert on GHC at all, so if someone who actually knows what they're talking about says that this concern is baseless, I agree that your approach is better. Michael _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
You do know, that you already *can* have safe Text and ByteString from
an overloaded string literal. On Tue, Apr 24, 2012 at 11:46 AM, Yitzchak Gale <[hidden email]> wrote: > Simon Peyton-Jones wrote: >> If you want validation of literal strings, then TH quasiquotes are the way to go: > > I agree. OverloadedStrings is, in effect, an unsafe replacement > for quasiquotes. People find OverloadedStrings easier to use > than quasiquotes, so its use in that way is becoming popular. > > What we need is a mechanism for allowing > string literals to have the type Text or ByteString > instead of String. > > I do not want to be forced to turn on UnsafeQuasiQuotes > every time I need a string literal. So in my opinion, > OverloadedStrings is the wrong mechanism for > providing Text and ByteString literals. > > Alternatives that have been suggested: > > o A hard-coded pragma to specify the type of string > literals in a module as Text or ByteString. > > o An extra method of IsString, of type QuasiQuoter, > that runs at compile time in a monomorphic context. > > o As above, but only check syntax at compile > time in a monomorphic context. That allows > a simpler API, without requiring any TH knowledge > in most cases. > > Thanks, > Yitz > > _______________________________________________ > Glasgow-haskell-users mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users -- Markus Läll _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
Markus Läll wrote:
> You do know, that you already *can* have safe Text and ByteString from > an overloaded string literal. Yes, the IsString instances for Text and ByteString are safe (I hope). But in order to use them, I have to turn on OverloadedStrings. That could cause other string literals in the same module to throw exceptions at run time. -Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
On Tue, Apr 24, 2012 at 12:35 PM, Yitzchak Gale <[hidden email]> wrote:
> Markus Läll wrote: >> You do know, that you already *can* have safe Text and ByteString from >> an overloaded string literal. > > Yes, the IsString instances for Text and ByteString are safe > (I hope). > > But in order to use them, I have to turn on OverloadedStrings. > That could cause other string literals in the same module > to throw exceptions at run time. > > -Yitz > > _______________________________________________ > Glasgow-haskell-users mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users Actually, the ByteString instance is arguably unsafe as well: {-# LANGUAGE OverloadedStrings #-} import qualified Data.ByteString.Char8 as S8 main = S8.putStrLn "שלום" It would be nice if usage of characters outside of the 0-255 range could be caught at compile time. Michael _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Michael Snoyman
On Tue, Apr 24, 2012 at 10:55, Michael Snoyman <[hidden email]> wrote:
> On Tue, Apr 24, 2012 at 11:36 AM, Erik Hesselink <[hidden email]> wrote: >> On Tue, Apr 24, 2012 at 08:32, Michael Snoyman <[hidden email]> wrote: >>> Here's a theoretically simple solution to the problem. How about >>> adding a new method to the IsString typeclass: >>> >>> isValidString :: String -> Bool >> >> If you're going with this approach, why not evaluate the conversion >> from String immediately? For either case you have to know the >> monomorphic type, and converting at compile time is more efficient as >> well. But we're getting pretty close to Template Haskell here. > > I could be mistaken, but I think that would be much harder to > implement at the GHC level. GHC would then be responsible for taking a > compile-time value and having it available at runtime (i.e., lifting > in TH parlance). Of course, I'm no expert on GHC at all, so if someone > who actually knows what they're talking about says that this concern > is baseless, I agree that your approach is better. But GHC already has all the infrastructure for this, right? You can do exactly this with TH. Erik _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
But if you want a string to be, say, an XML document then you want to
turn the string literal into an XML syntax tree (which is correct by the definition of the data types representing it). As this conversion can fail (all unicode strings are not valid representations of an XML syntax tree), you need to compile-time parse it. As you will need a compile-time parser for all such languages, then TH is the only reasonable choice -- or isn't it? On Tue, Apr 24, 2012 at 12:35 PM, Yitzchak Gale <[hidden email]> wrote: > Markus Läll wrote: >> You do know, that you already *can* have safe Text and ByteString from >> an overloaded string literal. > > Yes, the IsString instances for Text and ByteString are safe > (I hope). > > But in order to use them, I have to turn on OverloadedStrings. > That could cause other string literals in the same module > to throw exceptions at run time. > > -Yitz -- Markus Läll _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Erik Hesselink
On Tue, Apr 24, 2012 at 1:08 PM, Erik Hesselink <[hidden email]> wrote:
> On Tue, Apr 24, 2012 at 10:55, Michael Snoyman <[hidden email]> wrote: >> On Tue, Apr 24, 2012 at 11:36 AM, Erik Hesselink <[hidden email]> wrote: >>> On Tue, Apr 24, 2012 at 08:32, Michael Snoyman <[hidden email]> wrote: >>>> Here's a theoretically simple solution to the problem. How about >>>> adding a new method to the IsString typeclass: >>>> >>>> isValidString :: String -> Bool >>> >>> If you're going with this approach, why not evaluate the conversion >>> from String immediately? For either case you have to know the >>> monomorphic type, and converting at compile time is more efficient as >>> well. But we're getting pretty close to Template Haskell here. >> >> I could be mistaken, but I think that would be much harder to >> implement at the GHC level. GHC would then be responsible for taking a >> compile-time value and having it available at runtime (i.e., lifting >> in TH parlance). Of course, I'm no expert on GHC at all, so if someone >> who actually knows what they're talking about says that this concern >> is baseless, I agree that your approach is better. > > But GHC already has all the infrastructure for this, right? You can do > exactly this with TH. > > Erik Yes, absolutely. The issue is that TH can be too heavy for both the library author and user: * For the author, you now have to deal with generating some `Q Exp` instead of just producing your data with normal Haskell code. * For the user, you need to replace "foo" with [qqname|foo|]. There's also quite a bit of TH hatred out there, but I'm definitely not in that camp. Nonetheless, I *do* think it would be nice to avoid TH in this case if possible. Michael _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Yitzchak Gale
Why are potentially partial literals scarier than the fact that every value in the language could lead to an exception when forced?
On Tue, Apr 24, 2012 at 5:35 AM, Yitzchak Gale <[hidden email]> wrote:
_______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Erik Hesselink
On 24/04/2012 11:08, Erik Hesselink wrote:
> On Tue, Apr 24, 2012 at 10:55, Michael Snoyman<[hidden email]> wrote: >> On Tue, Apr 24, 2012 at 11:36 AM, Erik Hesselink<[hidden email]> wrote: >>> On Tue, Apr 24, 2012 at 08:32, Michael Snoyman<[hidden email]> wrote: >>>> Here's a theoretically simple solution to the problem. How about >>>> adding a new method to the IsString typeclass: >>>> >>>> isValidString :: String -> Bool >>> >>> If you're going with this approach, why not evaluate the conversion >>> from String immediately? For either case you have to know the >>> monomorphic type, and converting at compile time is more efficient as >>> well. But we're getting pretty close to Template Haskell here. >> >> I could be mistaken, but I think that would be much harder to >> implement at the GHC level. GHC would then be responsible for taking a >> compile-time value and having it available at runtime (i.e., lifting >> in TH parlance). Of course, I'm no expert on GHC at all, so if someone >> who actually knows what they're talking about says that this concern >> is baseless, I agree that your approach is better. > > But GHC already has all the infrastructure for this, right? You can do > exactly this with TH. No, Michael is right. The library writer would need to provide fromString :: String -> Q Exp since there's no way to take an aribtrary value and convert it into something we can compile. Cheers, Simon _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Daniel Peebles
On 24/04/2012 14:14, Daniel Peebles wrote:
> Why are potentially partial literals scarier than the fact that every > value in the language could lead to an exception when forced? My thoughts exactly. In this thread people are using the term "safe" to mean "total". We already overload "safe" too much, might it be a better idea to use "total" instead? (and FWIW I'm not sure I see what all the fuss is about either) Cheers, Simon > > On Tue, Apr 24, 2012 at 5:35 AM, Yitzchak Gale <[hidden email] > <mailto:[hidden email]>> wrote: > > Markus Läll wrote: >> You do know, that you already *can* have safe Text and ByteString > from >> an overloaded string literal. > > Yes, the IsString instances for Text and ByteString are safe (I > hope). > > But in order to use them, I have to turn on OverloadedStrings. That > could cause other string literals in the same module to throw > exceptions at run time. > > -Yitz > > _______________________________________________ Glasgow-haskell-users > mailing list [hidden email] > <mailto:[hidden email]> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > > > > > _______________________________________________ Glasgow-haskell-users > mailing list [hidden email] > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
|
In reply to this post by Daniel Peebles
Daniel Peebles wrote:
> Why are potentially partial literals scarier than the fact that every value > in the language could lead to an exception when forced? That's a legitimate question, but it's strange to hear it from you. People ask that same question about Haskell's static type system. Why bother? Every value could lead to an exception when forced. So we might as well check everything at run time. Wouldn't it be ironic if the one thing that every language other than Haskell is able to check at compile time, namely the static syntax of string literals, could only be checked at run time in Haskell? Especially when, with just a little care, we could easily continue to check it at compile time while still supporting string literals of type Text and ByteString. I guess I'm just not understanding your question. Thanks, Yitz _______________________________________________ Glasgow-haskell-users mailing list [hidden email] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
| Powered by Nabble | Edit this page |
