So here this codes makes the traffic light switch every three seconds: Instead, the time is provided as a parameter. This is not possible nor desirable in a pure functional language, as it would be a hidden side effect. In imperative language, one would probably have a getCurrentTime() function and call that from somewhere in our drawing generating. What is an animation? It is a picture that changes over time, where time can conveniently be understood as the number of seconds since the start of the animation. The CodeWorld API not only allows us to draw drawings, but also to run animations. Now the traffic light is green, but we want it to switch to red every now and then. Here we have applied a very important method in programming in general, and one that is even more powerful in functional programming (for reasons you will learn to appreciate later): We abstracted our code, by making the topCircle function abstract in the color, and the trafficLight function abstract in the state it is in. It is nicely complemented by the idea of projective programming: first solve a more general problem, then extract the interesting bits and pieces by transforming the general program into more specialised ones.”įor example, consider this pseudocode in a C/Java-ish sort of language: The wholemeal approach often offers new insights or provides new perspectives on a given problem. Wholemeal programming means to think big: work with an entire list, rather than a sequence of elements develop a solution space, rather than an individual solution imagine a graph, rather than a single path. “Functional languages excel at wholemeal programming, a term coined by Geraint Jones. Wholemeal programmingĪnother theme we will explore is wholemeal programming. Our journey through Haskell this semester will in large part be a journey from the specific to the abstract. Haskell is very good at abstraction: features like parametric polymorphism, higher-order functions, and type classes all aid in the fight against repetition. Taking similar pieces of code and factoring out their commonality is known as the process of abstraction. Also known as the “Abstraction Principle”, the idea is that nothing should be duplicated: every idea, algorithm, and piece of data should occur exactly once in your code. “Don’t Repeat Yourself” is a mantra often heard in the world of programming. “If it compiles, it must be correct” is mostly facetious (it’s still quite possible to have errors in logic even in a type-correct program), but you will have this experience much more likely in Haskell than in other languages. It’s much better to be able to fix errors up front than to just test a lot and hope for the best. Turns run-time errors into compile-time errors Given an expressive type system, just looking at a function’s type tells you a lot about what the function might do and how it can be used, even before you have read a single word of written documentation.Īnd it goes the other way: If you are using existing code, such as a library, and you are searching for a specific functionality, you often anticipate the type of the function you need, and you can find it based on that. Because Haskell’s type system is so expressive, this is a non-trivial design step and is an immense help in clarifying one’s thinking about the program. The first step in writing a Haskell program is usually to write down all the types. Helps clarify thinking and express program structure But this isn’t because static type systems per se are annoying it’s because C++ and Java’s type systems are insufficiently expressive! This semester we’ll take a close look at Haskell’s type system, which In fact, in languages like C++ and Java, they are annoying. Throughout this course, we will focus on three main themes. Programs with type errors will not even compile, much less run. Parallelism: Evaluating expressions in parallel is easy when they are guaranteed not to affect one another.įewer headaches: Simply put, unrestricted effects and action-at-a-distance makes for programs that are hard to debug, maintain, and reason about.Įvery Haskell expression has a type, and types are all checked at compile-time. But once you’ve made the shift, there are a number of wonderful benefits:Įquational reasoning and refactoring: In Haskell one can always “replace equals by equals”, just like you learned in algebra class. How is it even possible to get anything done without mutation or side effects? Well, it certainly requires a shift in thinking (if you’re used to an imperative or object-oriented paradigm). No mutation! Everything (variables, data structures…) is immutable.Įxpressions never have “side effects” (like updating global variables or printing to the screen).Ĭalling the same function with the same arguments results in the same output every time. Haskell expressions are always referentially transparent, that is:
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |