- Racket allows functional programming and other different paradigms that even hard-core programmers have never seen before.
- Lisp is a highly expressive language.
- Lisp will change your mind.
- Lisp is worth learning for a different reason--the profound enlightenment experience you will have when you finally get it. That experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.
- A compiler can take something that looks like plain arithmetic and convert it automatically into a format that the computer can execute.
- An interpreter is similar, although it performs the actions described in a human written program directly; there is no intermediate step that converts it all the way down to a computer format.
- For many functions, it makes a lot of sense to supply a lot of arguments at once, and with prefix notation, doing so is easy.
- Loops are just abbreviations for recursive functions.
- Computers are dumb pieces of hardware.
- Programmers use programming languages to turn computers into useful and entertaining gadgets.
- Racket is a programming language for making programming languages.
- Cutting the number of possibilities in half at each step is called a binary search.
- Binary search is frequently used in programming because it is remarkably effective at finding answers quickly.
- The define keyword is quite important for understanding Racket programs, as it is used to define variables and functions.
- Racket ignores spaces and line breaks when it reads code.
- The final value calculated in the function is returned automatically.
- The purpose of set!, pronounced "set bang", is to evaluate the expression and set the variable to the resulting value.
- It is practical to have one main function that starts--or restarts--the whole application.
- To understand any language--be it a human language or language for programming--requires two concepts from the field of linguistics. Computer scientists refer to them as "syntax" and "semantics". You should know that these are just fancy words for "grammar" and "meaning".
- Syntax is the collection of rules that a phrase must follow to qualify as a valid sentence.
- The actions that a computer performs in response to a program make up its semantics.
- Most programming languages have similar semantic powers.
- Having a simple syntax is a defining feature of the Lisp family of languages, including Racket.
- So keep in mind that Racket has only one way of organizing bits of code: parentheses. The organization of a program is made completely clear only from the parentheses it uses. And that's all.
- Symbols are another common type of data in Racket. A symbol in Racket is a stand-alone word proceeded by a single quote or "tick" mark (').
- Lists are a crucial form of data in Racket.
- Lists in Racket are held together with cons cells.
- A cons cell is made of two little connected boxes, each of which can point to any other piece of data, such as a string or a number.
- If x is the name for a cons cell, car extracts the left piece of data from x and cdr extracts the right one.
- There are three basic functions for manipulating lists in Racket: cons, first, and rest.
- When you call cons, Racket allocates a small chunk of memory, the cons cell, to hold references to the objects being linked.
- Structures, like lists, are yet another means of packaging multiple pieces of data together in Racket.
- To access the information in a structure field, we call the appropriate accessor function.
- In Racket, it is common practice to store data as lists of structures.
- A Racket predicate is just a function that returns either true or false.
- The basic idea behind a conditional expression is that some code is evaluated only under some condition.
- The cond expression is the classic way to do branching in Racket.
- When you write programs, you should create tests for almost all the functions in your code. As a matter of fact, you should write tests before you even write the function.
- Defining a constant and referencing it throughout the program is highly preferable to using literal constants everywhere. Once you have done so, you can change the value where it is defined, and then everything else that references the constant will use the new value as well. This provides a single point of control.
- A well-chosen data representation makes all the difference, because it almost always dictates how the code will be organized.
- Tick handlers are functions that step a world from one moment to the next.
- In Racket, graphical shapes are values just like numbers in other languages.
- As in physics, we think about any object as a point in the plane. With this representation, a check for collisions becomes especially easy. Objects collide when they both occupy the same point. We do pay a price for this simplicity, however.
- Functions in Racket are values, just like numbers, strings, and images.
- Since functions are treated as values, we can pass them into other functions as arguments. We can also return a function from a function.
- A function that consumes or produces another function is called a higher-order function, and it can compute all kinds of nifty things.
- With lambda, we can create nameless functions on the fly when we need them.
- The apply function takes a function and a list and applies the given procedure to the elements of the list.
- In Racket you can define a struct as a "child" of another struct.
- void is a function that produces nothing.
- Mutators make programming complex. We use them because they are powerful; they make changes to structs look concise. But this power is also difficult to control.
- Structures are good for representing objects with a fixed number of parts.
- You should get to know Racket's for loops because they are far more powerful than what you may have encountered. Racketeers are keenly aware of the advantages of lambda, map, andmap, filter, and friends, and therefore Racket provides many more kinds of for loops than you have ever seen. If you can wrap your head around them, you will write compact yet highly readable code.
- There are several variants of for loops. Each combines its results in a different way.
- As every college student knows, being lazy is on occasion a remarkably effective way to get work done. What we mean, of course, is that some work just goes away if you wait long enough.
- Lazy evaluation allows your program to delay computations until absolutely necessary. By doing so, it avoids a bunch of work that isn't needed in the first place.
- The simplest way to make a suspended computation is by wrapping a no-arguments lambda around an expression.
- Memoization is the technique of saving the result of a suspended computation in a hidden variable. If the result is needed again, it is enough to look at this hidden variable instead of rerunning the computation.
- A lambda in Racket creates a closure, which captures all the bindings in the lambda's context. This way, whenever a closure flows to a different scope, it can still reference all of its original bindings.
- Memoization eliminates the need to call any time-consuming thunk more than once.
- Fortunately, Racket has two built-in mechanisms to make your program lazy without you needing to write a lot of code. One of them is an entire language called Lazy Racket. To use it, change the #lang racket at the head of your program to #lang lazy. The idea behind lazy is that absolutely every computation is a lazy computation. Nothing is ever computed until it's needed, and everything is memoized.
- A promise represents a suspended computation that can be evaluated at a later date with force.
- Laziness procrastinates work until necessary.
- Memoization remembers the value of computations to avoid recomputing them.
- The strategy of search and evaluate is one idea behind John McCarthy's notion of AI. For games, this idea works amazingly well and truly invokes the perception of intelligence.
- The principle behind the minimax algorithm is "what is good for me is bad for my opponent", and vice versa. Hence, the algorithm minimizes the maximum damage an opponent can inflict during a turn. Roughly speaking, the algorithm proceeds in two steps. First, it assigns a value to each move in the tree, up to a certain level. Second, it determines the minimum of the maximal damage at each level of the tree, from the perspective of the current player. At the root of the game tree, the AI picks the move that results in the best possible outcome as far out as the algorithm can see.
- We do not want the AI to make an evaluation beyond a certain depth in the game tree. Otherwise, the AI forces every single level in the game tree, and we lose all the advantages of going lazy.
- The depth limit reduces the AI's intelligence but without it the program would run too slowly.
- Distributed programming requires a planned-out communication protocol.
- Designing a good protocol can save you a lot of work. Spend time on it.
- All members of the Lisp family come with incredibly powerful ways to add new syntax to the language. For better or worse, pedestrian programmers call this idea metaparogramming, and Lispers say macro programming. Regardless of what you call them, macros allow you to expand the vocabulary of your language.
- Many computational problems require substantial knowledge about the problem area, also known as the domain.
- Experts would much prefer to articulate solutions in a language that they understand, even if the language is just a special purpose programming language from our perspective.
- Racket makes it particularly easy to create new programming languages, including special-purpose languages.
- Like a compiler, the macros translate programs from the new language to plain Racket.
20170923
Realm of Racket by Matthias Felleisen
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment