|
391 | 391 | + 静态类型的优点:类型检查,更少的bug;compile time binding的优势,优化分析
|
392 | 392 | + 动态类型的优点:更自由的程序结构(想象Y-combinator、curry、memoize的函数签名会怎样);作者称,静态语言无法实现用于语法变化的宏
|
393 | 393 | + 软件的圣杯,可复用性(reusability)
|
| 394 | ++ counter的例子中,python等语言需要各种手工hack来弥补语言缺陷,这其实就是在扮演人肉解释器的角色,是所谓"任何C程序复杂到一定程度后,都会内置一个lisp解释器,或者程序员自己充当人肉解释器" |
| 395 | ++ 如果在程序中发现了大量的模式,则这本身就是错误;程序只应该反应要解决的问题,重复的模式说明抽象不够深,在做着人肉解释器的工作,应该考虑用宏进行syntactic abstraction了 |
| 396 | + |
| 397 | +#### 9. Peter novig: Design pattern in dynamic programming |
| 398 | ++ 16 of 23 patterns are either invisible or simpler |
| 399 | + + First-class types: Abstract-Factory, Flyweight, Factory-Method, State, Proxy, Chain-Of-Responsibility |
| 400 | + + First-class functions: Command, Strategy, Template-Method, Visitor |
| 401 | + + Macros: Interpreter, Iterator |
| 402 | + + Method Combination: Mediator, Observer |
| 403 | + + Combinator origned? |
| 404 | + + Multimethods: Builder |
| 405 | + + Multiple dispatch? |
| 406 | + + Modules: Facade |
| 407 | ++ First-Class Dynamic Types |
| 408 | + + First-Class: can be used and operated on where any other value or object can be used |
| 409 | + + Types or Classes are objects at run-time (not just at compile-time) |
| 410 | + + A variable can have a type as a value |
| 411 | + + A type or class can be created/modified at run-time |
| 412 | + + There are functions to manipulate types/classes (and expressions to create types without names) |
| 413 | + + No need to build extra dynamic objects just to hold types, because the type objects themselves will do |
| 414 | ++ First-Class Dynamic Functions |
| 415 | + + Functions are objects too |
| 416 | + + Functions are composed of methods |
| 417 | + + There are operations on functions (compose, conjoin) |
| 418 | + + Code is organized around functions as well as classes |
| 419 | + + Function closures capture local state variables (Objects are state data with attached behavior; Closures are behaviors with attached state data and without the overhead of classes.) |
| 420 | ++ Macros |
| 421 | + + Macros provide syntactic abstraction |
| 422 | + + You build the language you want to program in |
| 423 | + + Just as important as data or function abstraction |
| 424 | + + Languages for Macros |
| 425 | + + String substitution (cpp) |
| 426 | + + Expression substitution (Dylan, extend-syntax) |
| 427 | + + Expression computation (Lisp) |
| 428 | + + Provides the full power of the language while you are writing code |
| 429 | ++ Method Combination |
| 430 | + + Build a method from components in different classes |
| 431 | + + Primary methods: the “normal” methods; choose the most specific one |
| 432 | + + Before/After methods: guaranteed to run; No possibility of forgetting to call super ; Can be used to implement Active Value pattern |
| 433 | + + Around methods: wrap around everything; Used to add tracing information, etc. |
| 434 | + + Is added complexity worth it? |
| 435 | + + Common Lisp: Yes; Most languages: No |
| 436 | ++ Other Invisible Patterns: |
| 437 | + + The following patterns are invisible in dynamic languages, and usually implemented more efficiently |
| 438 | + + Smart Pointers: Pointers that manage copy constructors |
| 439 | + + Reference Counting: Automatic memory management |
| 440 | + + Closures: Functions with bound variables |
| 441 | + + Wrapper Objects: Objects with one data member, a primitive type such as a character or 32-bit integer |
| 442 | ++ New Dynamic Language Patterns: |
| 443 | ++ First-Class Patterns: make the design more explicit |
| 444 | + + Subroutine |
| 445 | + + Long ago, subroutine call was just a pattern |
| 446 | + + Involves two parts: call and definition |
| 447 | + + Nowadays, made formal by the language |
| 448 | + + Note there are still 2 parts in formal use of pattern |
| 449 | + + Many patterns are harder to define formally because their use is spread out over more than two places |
| 450 | + + Abstract class |
| 451 | + + Generic function |
| 452 | + + Macro |
| 453 | ++ Iterators: a study of C++, Dylan, Smalltalk and Sather |
| 454 | + + Iterator |
| 455 | + + C++ STL |
| 456 | + + Internal Iterator |
| 457 | + + C/C++ |
| 458 | + + Smalltalk: Passing a block to the `do` method: `employees do : [ :x | x print] ` |
| 459 | + + Inconventient for iteration over multiple collections |
| 460 | + + How dou you compare two collections? |
| 461 | + + How do you do element wise A:= B + C? |
| 462 | ++ Coroutine |
| 463 | + + Intent: separate out distinct kinds of processing; save state easily from one iteration to the next |
| 464 | + + Implementation: Most modern language implementations support an interface to the OS’s threads package. But that has drawbacks: |
| 465 | + + No convenient syntax (e.g. yield, quit) |
| 466 | + + May be too much overhead in switching |
| 467 | + + Problems with locking threads |
| 468 | + + Implementation: Controlled uses of coroutines can be compiled out (Sather iters, Scheme call/cc) |
| 469 | ++ Control abstraction |
| 470 | + + Most algorithms are characterized as one or more of: |
| 471 | + + Searching: (find, some, mismatch) |
| 472 | + + Sorting: (sort, merge, remove-duplicates) |
| 473 | + + Filtering: (remove, mapcan) |
| 474 | + + Mapping: (map, mapcar, mapc) |
| 475 | + + Combining: (reduce, mapcan, union, intersection) |
| 476 | + + Counting: (count) |
| 477 | + + Code that uses these higher-order functions instead of loops is concise, self-documenting, understandable, reusable, usually efficient (via inlining) |
| 478 | + + Inventing new control abstractions is a powerful idea |
| 479 | ++ Mixing compile time and run time: Memoization, Compiler, Run time loading, Partial Evaluation |
| 480 | ++ Memoization |
| 481 | + + Intent: Cache result after computing it, transparently |
| 482 | + + Complications: Know when to empty table, how many entries to cache, when they are invalid |
| 483 | ++ Compiler |
| 484 | + + Like the Interpreter pattern, but without the overhead |
| 485 | + + A problem-specific language is translated into the host programming language, and compiled as normal |
| 486 | + + Requires complex Macro capabilities May or may not require compiler at run time |
| 487 | + + A major factor when Lisp is faster than C++ |
| 488 | + + In a sense, every macro definition is a use of the Compiler pattern (though most are trivial uses) |
| 489 | + + Examples: Decision trees; Window, menu layout; Definite Clause Grammar; Rule-Based Translator |
| 490 | ++ Run-Time Loading |
| 491 | + + Intent: Allow program to be updated while it is running by loading new classes/methods (either patches or extensions). Good for programs that cannot be brought down for upgrades. |
| 492 | + + Alternative Intent: Keep working set small, start-up time fast by only loading features as needed |
| 493 | + + Implementation: DLLs, dynamic shared libraries. |
| 494 | + + Language must allow redefinition or extension |
| 495 | ++ Partial Evaluation |
| 496 | + + Intent: Write literate code, compile to efficient code |
| 497 | + + Implementation: Mostly, at whim of compiler writer (Harlequin Dylan, CMU Lisp compilers good at it) |
| 498 | + + Alternative Implementation: Define a problem specific sublanguage, write a compiler for it with partial evaluation semantics |
| 499 | + + Example: Macro call horner(1 + 2 * x + 3 * x ^ 2) expands to 1 + x * (2 + 3 * x) |
| 500 | ++ Design Strategies |
| 501 | + + What to Build |
| 502 | + + Class Libraries / Toolkits: Generic (sets, lists, tables, matrices, I/O streams) |
| 503 | + + Frameworks: Specialized (graphics), “Inside-Out” (callbacks) |
| 504 | + + Languages: Generic or Specialized (Stratified Design) |
| 505 | + + Design Process: Source control, QA, Design rationale capture, ... |
| 506 | + + Metaphors: Agent-Oriented, Market-Oriented, Anytime Programming |
| 507 | + + How to Build |
| 508 | + + Programming In a language: The design is constrained by what the language offers |
| 509 | + + Programming Into a language: The design is done independently of language, then the design is implemented using features at hand |
| 510 | + + Programming On a language: The design and language meet half way. This is programming into the language you wish you had; a language you build on the base language. Sometimes called Stratified Design. |
| 511 | + + Abstraction |
| 512 | + + Data abstraction: encapsulation, first-class types |
| 513 | + + Functional abstraction: first-class functions, closures |
| 514 | + + Syntactic abstraction: macros, overloading |
| 515 | + + Control abstraction: macros and high-order functions |
| 516 | + + Design process abstraction: abstract away files, deal with phases of project, explicit development process |
| 517 | + + Resource abstraction: separate what it takes to do it from what is done (See Open Implementation) |
| 518 | + + Storage abstraction: garbage collection, no new, slot access and function calls have same syntax |
| 519 | + + How to Write |
| 520 | + + (Literate programming vs. class-oriented/obsessed) |
| 521 | + + Specific Design Strategies |
| 522 | + + (Open Implementation; English Translation) |
| 523 | + + Metaphors: The Agent Metaphor |
| 524 | + + (Is agent-oriented programming the next big thing?) |
| 525 | + + Combining Agent Components |
| 526 | + |
| 527 | +#### 9. 杂项 |
| 528 | ++ Agent-oriented: 面向方法 |
| 529 | ++ Iterator的一个分支是Internal iterator,它接收一个callback,用递归遍历每个元素触发这个callback;缺点是无法同时遍历多个容器 |
| 530 | ++ 宏的比较 |
| 531 | + + C/C++: 文本替换(String substitution) |
| 532 | + + Dylan: 表达式替换(Expression substitution) |
| 533 | + + Lisp: 表达式计算(Expression computation)、语法变换 |
| 534 | ++ 三种境界: |
| 535 | + + Programming in a language: 用语言提供的特性编程 |
| 536 | + + Programming into a language: 语言没有提供的特性,人工模拟 |
| 537 | + + Programming on a language: 在host programming language之上做一门DSL,然后以DSL编程 |
| 538 | ++ 抽象 |
| 539 | + + Data abstraction: encapsulation, first-class types |
| 540 | + + Functional abstraction: first-class functions, closures |
| 541 | + + Syntactic abstraction: macros, overloading |
| 542 | + + Control abstraction: Searching, Sorting, Filtering, Mapping, Combining, Counting.. higher-order functions |
0 commit comments