Skip to content

Instantly share code, notes, and snippets.

@harms
Created September 4, 2012 05:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harms/3617162 to your computer and use it in GitHub Desktop.
Save harms/3617162 to your computer and use it in GitHub Desktop.
Three versions of 'dig', moving away from statement-based conditionals.
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