Does anybody find this Scheme code readable?
raw.githubusercontent.com
raw.githubusercontent.com
- Defining a new iteration macro FOR that's used in just a single function, has a very odd syntax, and that's way too generic for uses.
- The first parameter to the PICK function (the position) is a pair. That might make sense if those pairs were values that had been passed throughout the program. But actually every place where PICK is called constructs a totally new pair just for that call. It should be split to separate ROW and COLUMN parameters. This would remove a lot of noise at the call sites.
- Or alternatively, if the parameter is kept as is, all of this boilerplate: (cons (- (car kpos) 1) (- (cdr kpos) 1)) should be replaced by calls to a function that does both the consing, caring and cdring. Something like (add-to-position kpos -1 -1)
- The is-piece-foo functions use eq? and equal? inconsistently.
- The CH-HOF function is full of copy-paste boilerplate with each instance having tiny tweaks. Turning these into calls to sensibly parametrized functions would make a big difference.
- There's like 20 instances of (set! rsc (+ rsc 0)) . What in the world is that supposed to achieve?
- The indentation of IFs is horrible. Putting the THEN branch on the same line as the test, and then putting the ELSE on the next line is just criminal. Especially given how deeply nested some of the condition expression are, it's very hard to notice that it's in fact a two-branch rather than one-branch IF. It's as if this code was deliberately written to be obfuscated.
If you're not using DrRacket, then please start using it. I learned what was then Scheme from SICP[2], but I've heard that the Little Schemer is perhaps a bit more approachable. Try starting with it[3].
[1] That moment when you realize it's been over fifteen years since you started college...Yeesh.
[2] https://en.wikipedia.org/wiki/Structure_and_Interpretation_o...
[3] http://stackoverflow.com/questions/13003850/little-schemer-a...
But if the author's goal was maximum readability, they might have considered doing away with the abbreviations.
Also I notice code like:
(- (cdr kpos) 1))
How is that possible? If kpos is a list of two elements to represent the king's position, so (cdr kpos) should be a list, not compatible with subtraction.For example:
#;4> (- (cdr '(1 2)) 1)
Error: (-) bad argument type: (2)After looking carefully, the kpos is the result of the function find. In this case it's a cons with the row and the column of the king. So the code that runs is more like
(define kpos (cons 1 2))
(- (cdr kpos) 1)
In this case, for clarity I prefer to use a struct instead of a cons to save the position (struct cell (row col))
(define kpos (cell 1 2))
(- (cell-col kpos) 1)A couple of things could be improved for me; I almost never use abbreviated variable names unless it's for simple iteration.
Also things like this being repeated on 8 lines, just screams for some sort of abstraction:
(set! rsc (+ rsc 3)) (set! rsc (+ rsc 0))) (set! rsc (+ rsc 0))My biggest Scheme program is [1]. I wrote it years ago, but I can still read it. Using sanely named variables is key.
[1] https://github.com/tshatrov/scriptfu/blob/master/animstack.s...
Here's some Racket code in DrRacket: http://i.imgur.com/GKveHtl.jpg
You get used to it pretty quickly, and good editors will provide paren matching and completion.
1. That is badly written code. 2. I'm a bad programmer. 3. Scheme's syntax is ugly.
What do you think?
You're fooled on this because so many languages are so similar -- if you know C++, you can trivially read Java and C# and Python, and even languages that are a bit further afield like Javascript and Perl still are heavily influenced by C, so don't seem too odd.
But Scheme is a whole new family of languages. It's like being an English reader and looking at Greek text as opposed to Spanish. It's not that Greek is harder than Spanish, it's that Spanish is closer to what you already know.
Scheme has mutable state. Scheme has unmarked side-effects. Scheme has variables, as opposed to tags applied to constant values.
Scheme was an entirely new kind of language back when lambda expressions were Heavy Deep Magic and dynamic typing was something you did when your Flexowriter was well-oiled (hyperbole intentional). These days, it's no weirder than Javascript or the more modern dialects of Java or Visual C#.Net. Hell, even C++ is getting lambdas and closures, and that's a Serious Business COBOL-Replacement Language.
Modern Algol dialects are Scheme in everything except syntax, and now that metaprogramming (Ruby, to begin with) is beginning to catch on, I fully expect language designers to re-invent some shambolic version of s-expressions when they realize that metaprogramming in Algol syntax is hard.
Scheme won. It's just that its victory was suppressed for political reasons.
Try it with an interpreter running.
I found it reasonably readable. The only criticism I had, offhand, was that the predicates like 'is-piece-knight?' were a bit verbose: the query mark at the end is understood to label a predicate, so the 'is-piece-' was redundant. I'd have written 'knight?' instead. That's pretty nit-picky though, and I don't think the current convention really detracts from its readability.
[1] If Lisp is So Great: http://paulgraham.com/iflisp.html
On the plus side: It's minimal and doesn't spend much time building abstractions on top of the basic lists/etc. that scheme provides. However, it certainly isn't pretty.
For instance: Things like the king & knight checks are really pretty ugly brute force solutions.
Similarly, the variable & function naming really is rather unclear and very poorly commented--some of that may be use of things idiomatic to scheme that I'm unfamiliar with though.
2. Always a possibility, I certainly don't know you. ;)
3. Some people certainly have said that before and probably will again. This is really just a personal preference thing, I think.