Created
September 4, 2012 05:40
-
-
Save harms/3617162 to your computer and use it in GitHub Desktop.
Three versions of 'dig', moving away from statement-based conditionals.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NB. These snippets are involved with a J implementation of RCRPG: http://rosettacode.org/wiki/Category:RCRPG | |
NB. That solution is still being written, so has not yet been posted to that website. | |
NB. The exercise of eliminating control-statements was largely inspired by the conversation on Twitter with @Huperniketes that included this comment: https://twitter.com/Huperniketes/status/240917975228637185 | |
NB. NOTE: The version posted earlier, with tacit definitions of verbs such as fail_tool, did not work. The final portion has been corrected to fix this. | |
NB. Here's the original version of the verb 'dig' (omitting definitions of included names) | |
dig=: 3 : 0 | |
if. PC_equipped includes 1 Sledge do. | |
FROM=. zyx PC_location | |
TO=. FROM + direct y | |
assure_room TO | |
DELTA=. ways/ FROM,:TO | |
NO_PRIOR_PASSAGE=. 0 -: */ , DELTA *. (locate FROM,:TO) { WAY | |
if. NO_PRIOR_PASSAGE do. | |
'passageways' alter WAY +. DELTA (locate FROM,:TO)} WAY | |
report DUG_THE_PASSAGEWAY | |
else. | |
report CANNOT_DIG_ALREADY_EXISTS | |
end. | |
else. | |
report CANNOT_DIG_NO_TOOL | |
end. | |
0 | |
) | |
NB. The version above is weak for not reporting both failures if both criteria are not met. Continuing to use control-statements, the following version corrects that weakness. Definition of the verb 'has_no_passage_to' is also listed since that's a new definition as of this version: | |
dig=: 3 : 0 | |
if. PC_equipped includes 1 Sledge do. | |
CAN_DIG=. 1 | |
else. | |
CAN_DIG=. 0 | |
report CANNOT_DIG_NO_TOOL | |
end. | |
if. PC_location has_no_passage_to DIRECTION_said=. y do. | |
CAN_DIG=. CAN_DIG *. 1 | |
else. | |
report CANNOT_DIG_ALREADY_EXISTS | |
end. | |
if. CAN_DIG do. | |
FROM=. zyx PC_location | |
TO=. FROM + direct y | |
assure_room TO | |
DELTA=. ways/ FROM,:TO | |
'passageways' alter WAY +. DELTA (locate FROM,:TO)} WAY | |
report DUG_THE_PASSAGEWAY | |
end. | |
0 | |
) | |
has_no_passage_to=: 4 : 0 | |
-. +./ (x { WAY) *. WAYS {~ DIRECTION_text i. y | |
) | |
NB. Next is a listing for a version that has no statement-based control structures. The code for accomplishing the digging has been segregated into a separate verb, 'make_passageway'. The conditional logic proper, done by matching a permutation, is in 'resolve': | |
dig=: 3 : 0 | |
HAS_TOOL=. PC_equipped includes 1 Sledge | |
NO_HOLE=. PC_location has_no_passage_to DIRECTION_said=. y | |
CRITERIA=. HAS_TOOL, NO_HOLE | |
fail_tool=. 4 : ' report CANNOT_DIG_NO_TOOL ' | |
fail_hole=. 4 : ' report CANNOT_DIG_ALREADY_EXISTS ' | |
succeed =. 4 : ' report DUG_THE_PASSAGEWAY label_here. x make_passageway y ' | |
Possibilities=. (fail_tool,fail_hole) ` fail_tool ` fail_hole ` succeed | |
PC_location (Possibilities resolve CRITERIA)`:6 DIRECTION_said | |
) | |
resolve=: 4 : 0 | |
POSSIBLE=. x | |
ACTUAL=. y | |
(I. (#:i.#POSSIBLE) -:"1 _ ACTUAL) { POSSIBLE | |
) | |
make_passageway=: 4 : 0 | |
FROM=. zyx x | |
TO=. FROM + direct y | |
assure_room TO | |
DELTA=. ways/ FROM,:TO | |
'passageways' alter WAY +. DELTA (locate FROM,:TO)} WAY | |
) | |
NB. I like several things about this last version. I love eliminating the local noun 'CAN_DIG' with its multiple-assignments. I like the first three lines, and I like their relationship to the gerund list at the left of 'resolve'. (The parenthesized verb on the right will be better named.) | |
NB. One thing I'm not so fond of is the way this version of 'dig' requires greater fluency in J to understand. I also don't like the way the checks and the consequences involve values with separate assignments (e.g. the pair HAS_TOOL and fail_tool). I don't like how little this gives me code that's useful beyond this particular command. (In the context of this exercise, 'dig' is a command.) And it doesn't give me a sense of reducing the amount of source-code used to accomplish this. | |
NB. I suspect I can create abstractions that will apply here and in similar situations. That will relieve the unhappy sense that this code is all special-purpose, but it will again raise the bar as to how fluent one must be with J in order to follow what's going on with ease. Since the main intended audience for this code are programmers who do not know J, that seems a significant cost. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment