38
13
Recently I had the pleasure of writing a Haskell program that could detect if the NegativeLiterals
extension was engaged. I came up with the following:
data B=B{u::Integer}
instance Num B where{fromInteger=B;negate _=B 1}
main=print$1==u(-1)
This will print True
normally and False
otherwise.
Now I had so much fun doing this I'm extending the challenge to all of you. What other Haskell language extensions can you crack?
Rules
To crack a particular language extension you must write a Haskell program that compiles both with and without the language extension (warnings are fine) and outputs two different non-error values when run with the language extension and it turned off (by adding the No
prefix to the language extension). In this way the code above could be shortened to just:
data B=B{u::Integer}
instance Num B where{fromInteger=B;negate _=B 1}
main=print$u(-1)
which prints 1
and -1
.
Any method you use to crack a extension must be specific to that extension. There may be ways of arbitrarily detecting what compiler flags or LanguageExtensions are enabled, if so such methods are not allowed. You may enable additional language extensions or change the compiler optimization using -O
at no cost to your byte count.
Language extensions
You cannot crack any language extension that does not have a No
counterpart (e.g. Haskell98
, Haskell2010
, Unsafe
, Trustworthy
, Safe
) because these do not fall under the terms outlined above. Every other language extension is fair game.
Scoring
You will be awarded one point for every language extensions you are the first person to crack and one additional point for every language extension for which you have the shortest (measured in bytes) crack. For the second point ties will be broken in favor of earlier submissions. Higher score is better
You will not be able to score a point for first submission on NegativeLiterals
or QuasiQuotes
because I have already cracked them and included them in the body of the post. You will however be able to score a point for the shortest crack of each of these. Here is my crack of QuasiQuotes
import Text.Heredoc
main=print[here|here<-""] -- |]
Can programs take input? – H.PWiz – 2018-01-21T19:19:03.520
Can we require more than one extension, but only toggle one – H.PWiz – 2018-01-21T19:25:45.573
@H.PWiz programs should not take input. You may require additional language extensions if you wish. – Post Rock Garf Hunter – 2018-01-21T19:43:43.023
3
I think this is a list of all valid options
– H.PWiz – 2018-01-21T20:32:06.1231Note that my above comment does not include
NondecreasingIndentation
for obvious reasons – H.PWiz – 2018-01-21T21:12:31.567If certain circumstances raise an exception and the program can recover from it (printing a message to stderr), is this acceptable behaviour? Asking because of this.
– ბიმო – 2018-01-22T07:58:43.140@BMO You are free to print to STDERR during compilation for warnings but at run time STDERR should be empty. – Post Rock Garf Hunter – 2018-01-22T14:42:37.590
How should other flags be scored? See the comments here for context.
– Laikoni – 2018-01-22T19:04:15.857I'd suggest that language extensions other than the one you're testing for should count for bytes. Mostly because I'm disappointed about all the
TemplateHaskell
use I see here. – Ørjan Johansen – 2018-01-23T02:15:08.633@ØrjanJohansen In retrospect it might not have been a good idea to let all language extensions get by for free, but I don't intend to change the rules now. – Post Rock Garf Hunter – 2018-01-23T04:59:21.510
4I think this title is misleading, as the only language you can use is Haskell. How about
Wait, what language extension is this?
Or something completely different. – MD XF – 2018-01-25T03:44:57.693@MDXF All the languages are different they are just all in the Haskell family. – Post Rock Garf Hunter – 2018-01-25T03:45:50.123
I think you should drop the requirement for a
No
counterpart. I'm not sure, but I think there might be at least one game to play with safe Haskell. – dfeuer – 2019-03-06T18:01:08.830@dfeuer The problem with extensions that don't have
No
counter part is it is hard to tell what we should be comparing it to.No
counterparts make it nice and clear. – Post Rock Garf Hunter – 2019-03-06T18:04:29.423@SriotchilismO'Zaic, in those cases, compare to the effect of not giving the option. The same goes for
No
options without a positive counterpart, if there are any. – dfeuer – 2019-03-06T19:25:20.1271I'm quite curious whether it's possible to crack
RelaxedPolyRec
, for a compiler ancient enough to actually support turning it off. (The option hung around, with documentation, for some years after it stopped doing anything.) – dfeuer – 2019-03-07T08:51:40.277@dfeuer I don't have an old compiler to check, but would
x=0^y;y=seq(x/)0;y::Int
work? (NeedsNoMonomorphismRestriction
.) – Ørjan Johansen – 2019-03-08T04:47:47.237@ØrjanJohansen, my intuition for
NoRelaxedPolyRec
is rather poor. The description of the restriction in the Haskell 98 Report is just awful. – dfeuer – 2019-03-08T05:02:40.627@ØrjanJohansen, I'm really not sure. GHC is the only compiler I've been able to find that (at one point) claimed to be able to turn the extension on and off. As far as I can tell, there's no way to turn it on in Gofer, and the only way I've found to (maybe!) turn it off in Hugs also disables all other extensions. I don't see any mention of it in the nhc98 docs. It's probably still possible to get some really old GHC versions.... – dfeuer – 2019-03-08T05:41:21.773
@dfeuer
x()=0^y;y=seq(x()/)0;y::Int
ought to work withoutNoMonomorphismRestriction
. However, changing between Hugs and Haskell 98 mode (which I'm guessing you mean) doesn't change the result. :( – Ørjan Johansen – 2019-03-08T06:13:08.717Yes, that's what I meant. That was the only option I saw that looked like it might disable the extension. I could've missed something though. – dfeuer – 2019-03-08T06:16:34.560
1
@dfeuer Looking at this ticket it seems like GHC 6.12.1 supported turning it off.
– Ørjan Johansen – 2019-03-08T06:35:50.040Are we allowed to print more than one value? – dfeuer – 2019-03-08T21:31:32.700
@dfeuer What does it mean to print more than one value? – Post Rock Garf Hunter – 2019-03-08T21:32:36.413
For example, to print two numbers, one on each line. Also, we need an answer about whether the output is allowed to be empty, or just a newline, sometimes. Do the things printed have to represent Haskell values, or can they be arbitrary strings? – dfeuer – 2019-03-08T21:34:22.650
@dfeuer Yeah, I don't care whether things are haskell values or how many lines they are on etc. As long as the outputs are different and non-error. (output to STDERR or non-zero exit code) – Post Rock Garf Hunter – 2019-03-08T21:35:56.043
What are the rules about compiler flags (e.g.,
-O
)? – dfeuer – 2019-03-08T22:00:32.940@dfeuer I'd like to say that you can use whatever flags you want at no cost, but I am pretty sure there are ways that you can just write all your code as flags and thus "score" zero bytes. I went ahead and said you can use the various
-O
s at no additional cost, if there is any other flags you or any one else would like me to add I'd probably do so. – Post Rock Garf Hunter – 2019-03-08T22:04:16.017