Wizards and warriors, part five
ericlippert.com
ericlippert.com
As soon as you want to start encoding "rules" for "encoding the allowed transformations of your data," then congratulations, you've invented something called a "function." Functions are rules for expressing what you are allowed to do.
fn wield(Wizard, Wand) // Wizards can wield wands.
fn wield(Warrior, Sword) // Warriors can wield swords.
fn capability(Player, wield_fn=wield(Player, Weapon)) // Players can wield weapons.
Now there's no way to violate these rules unless your users can compile functions and pass them into your code.>There is no need to figure out “which class does the rule about paladins vs werewolves go in?” The rule goes in a rulebook, end of story. Like I said, Inform7 is amazing.
I've never seen someone so impressed by global functions before.
I honestly can't think of a language that even support overloading of methods based on run time types.
And the moment you don't have overloaded methods based on run time types you have to do something interesting like this to do the work.
Dylan allows sealing of generic functions to limit extensibility where needed and can use that information (along with other information) to optimize, generate warnings, etc.
define class <weapon> (<object>) end;
define class <sword> (<weapon>) end;
define class <wand> (<weapon>) end;
define class <person> (<object>) end;
define class <wizard> (<person>) end;
define class <warrior> (<person>) end;
define method wield (who :: <wizard>, what :: <wand>) => ()
...
end;
define method wield (who :: <warrior>, what :: <sword>) => ()
...
end;Clojure does with multimethods ( http://clojure.org/runtime_polymorphism ). I suspect lisp with meta object protocol does too, but I only heard about it, so can't confirm.
EDIT: deleted my solution that worked without method overloading at all, cause I missed some constraints.
(derive ::wizard ::person)
(derive ::warior ::person)
(derive ::weapon ::thing)
(derive ::dagger ::weapon)
(derive ::sword ::weapon)
(derive ::staff ::weapon)
;; defines dispatch function that returns (inheritable) categories to dispath
;; it's very simple in this case
(defmulti wield! (fn [p1 p2 thing]
[(type p2) (type thing)]))
(defmethod wield! [::person ::thing] [p1 p2 thing]
(say! p1 p2 " refuse"))
(defmethod wield! [::person ::dagger] [p1 p2 thing]
(take! p2 p1 thing)
(say! p1 p2 "accepts."))
(defmethod wield! [::wizard ::staff] [p1 p2 thing]
(take! p2 p1 thing)
(say! p1 p2 " gladly accepts."))
(defmethod wield! [::warrior ::sword] [p1 p2 thing]
(take! p2 p1 thing)
(say! p1 p2 " gladly accepts."))
It obviously could be done in half the lines without using multimethods, but the result would be much less extensible.BTW, with just 2 lines you can add gandalf and it just works (because there are no conflicting methods right now).
(derive ::gandalf ::wizard)
(derive ::gandalf ::warrior)
If there were any - you can set preferences to avoid errors.Now, what happens when a vampire or a werewolf bites a warrior? Here is a rough sketch:
(unless (typep target 'werewolf) (with-scheduling ...))He just ended up with a language where all code is written in a specific language programmers have to learn and errors are in another language.
The generic constraint solution he had in the middle (part 2) was actually pretty decent because hey: if Wizards and Warriors can't yield the same weapons - and the weapon is a property of the supertype then __they are not interchangeable as players__. You need a different interface.
https://inst.eecs.berkeley.edu/~cs61a/su13/lab/lab06a/lab06a...
You can stick your pseudocode into the "give" function: https://inst.eecs.berkeley.edu/~cs61a/sp15/lab/lab10/adventu...
I'm not sure it's explicit in the original article, but I tend to agree with the sentiment that it's a lot more fun to learn about interpreters and databases when you're making games rather than corporate infrastructure (although I can't deny that building corporate infrastructure has its moments)
Joel Spolsky talks about using the compiler to catch errors on p. 68 of "The Best Software Writing I"
https://books.google.com/books?id=vPvhzDqZlaAC&pg=PA68&lpg=P...