Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using @-patterns to get the pattern value redundant?

I'm going through Write Yourself a Scheme in 48 Hours, and in it I've come across some seemingly redundant code; they use @-patterns and then return the value itself, let me explain.

Here's the relevant code:

data LispVal = Atom String
             | List [LispVal]
             | DottedList [LispVal] LispVal
             | Number Integer
             | String String
             | Bool Bool

eval :: LispVal -> LispVal -- code in question starts here
eval val@(String _) = val
eval val@(Number _) = val
eval val@(Bool _)   = val
eval (List [Atom "quote", val]) = val

It seems to me that the entire eval function could just as easily be re-written as

eval :: LispVal -> LispVal
eval (List [Atom "quote", val]) = val
eval val = val

And have the bottom case account for all the @-patterns in the original code.

Am I mistaken in thinking this, and is there an actual benefit of doing it the way they did? Or is the other way more concise?

like image 798
Electric Coffee Avatar asked Dec 20 '22 02:12

Electric Coffee


1 Answers

One difference is that the original code is undefined for values constructed with Atom, i.e. there is no line

eval val@(Atom _) = val

And whether this is a copy’n’paste error or not, it highlights the important difference in style:

The first style encourages you to think about each value individually, making an explicit assertion “this is the right equation for this”. If you later add more constructors t othe LispVal type, you get runtime errors (or compiler warnings with -fwarn-incomplete-patterns, which is good practice).

The second style asserts: eval will only have to look at List values, and all others can be treated individually. In particular, later additions to the data type should work just as well, and you don’t want to be bothered about this function then.

Operationally, they are equivalent.

like image 136
Joachim Breitner Avatar answered Dec 25 '22 23:12

Joachim Breitner