Here are my comments after a brief reading:
First, if you intend to make this library fit for general use, add documentation in comments for the provided functions. See the Racket style guide for examples
Also, if you intend to make this a more general library, don't include default arguments (e.g. for ircbot-connect) unless they make sense for all users. ...
When I went through the WYAS48 I made the same decision of breaking the bits of eval off into smaller functions. I found this made testing easier since I could focus on just one function at a time.
I find that having a function be one massive bunch of logic is not helpful. In an imperative language the equivalent would be a single function with a ton of if/...
I can only speak to the JS code - which looks pretty good, by the way... except:
You're modifying the array you're folding. In fact, you're truncating it completely due to your use of shift. So your function has destructive side-effects. After the fold, you have your answer, but you've lost the question, so to speak.
var question = [2, 3, 7];
Speaking for Scheme over here; looks pretty good. I have precisely three aesthetic quibbles, but you got the essence. Also, whether by accident or intention, you aren't doing the Scheme version destructively, so the comments Flambino had for your JS version don't apply here.
The base case in a list recursion is usually expressed as (null? foo) rather than (...
to get the bike shedding out of the way: i prefer tibbe's style guide. in that spirit, have blank lines between instance declarations, use a newline after an instance where. and please stick to 80 char lines.
you might like to order your functions somehow. the order is imo pretty chaotic.
to the more substantial review.
tl;dr: See the bottom of the post for my implementation of the function.
As mentioned in Ben Rudgers's answer, lists should not be treated as vectors, as they are not random-access. That means you should not be using numeric indices, list lengths, etc.
Lists are recursive data structures
Lists are recursive data structures: a list is either an empty list, ...
So, any time you want to write a "helper" recursive function, the standard way to write that is to use a named let. So here's how I might restructure your program (but keeping the same algorithm):
(define (sum-multiples start end)
(let loop ((sum 0)
(cond ((>= i end) sum)
((or (zero? (modulo i 3))
Better programming practice would be to decompose the problem in such a way that the procedures adhere to the Single Responsibility Principle. In other words, the answer should be obtained by evaluating something like
(sum (filter (multiple-of-any? 3 5) (range 0 1000)))
… which reads just like the problem to be solved.
Here's a set of functions that ...
Here are some general points before I start on more specific points:
I don't see any unit tests. Racket programmers often write many unit tests for each function. You can use the module+ construct and rackunit to easily write internal unit tests.
Indentation is important for clarity. I couldn't tell that everything was internal to heap at first because of ...
What you've written is called "selection sort", and it works fine. It's not the best sort, but it's not bad, either. It's one of a class called "n^2" sorts, because it generally runs in time proportional to the square of the length of the list.
Selection sort is a somewhat painful sort to write in a recursive style, because removing an element from a list ...
Yes, those inner functions do get reassigned at each invocation, but that's cheap. In sane implementations, the inner function bodies are compiled just once, with a new lexical environment attached each time.
(In other sane implementations, the inner functions could be inlined into the outer function, but still, it's only compiled once, not for every ...
Starting at the top, you have a lot of unused imports. Fortunately, DrRacket can tell you which imports are unused, since it will highlight them in red when you hover your mouse over them. Additionally, if you click the Check Syntax button, it will color all the unused imports red. Using that, we can trim the import list down to the following set:
Overall, the code is quite clean and understandable. Though, I have never done anything like you are doing, but here are some notes about the code:
the Token and TokenTypes classes may use "__slots__" for faster attribute access and memory savings
the char in builtin_map.keys() can and should be replaced with just char in builtin_map to avoid creating the ...
So either a is the minimum of the list in which case b and c or it's not and it's one of the numbers you want to keep. The other is the max of b and c.
(define (f a b c)
(if (or (> a b) (> a c))
(sum-of squares a (max b c))
(sum-of-squares b c)))
(define (square x) (* x x))
(define (sum-of-squares a b) (+ (square a) (square b)))
Converting strings into lists of characters, then reassembling strings, is quite wasteful of memory. The usual implementation technique for this function should be to scan for the character you're looking for, and then use substring to extract the substring.
However, as the OP correctly points out, in R7RS, string-ref should be avoided because it's O(n). ...
Your answer makes an implicit assumption:
Racket's built-in shuffle assigns each list element with a random number as a sort key, then sorts the list, which provides an O(n log n) runtime. However, I'd like something that's O(n), and that's where Fisher-Yates comes in.
That assumption is that O(n) will necessarily be faster than O(n log n). I don't think ...
Racket tends to use two space indentation rather than Python's four spaces. This keeps code from indenting too far to the right and because Lisps allow multiple expressions on a single line, reduces the issues with lines becoming uncomfortably long. Keep in mind that "left banana"s [ ( ] are also there to help the reader.
The big ...
Hint: you’ll need a sum-of-factors subprocedure.
So I would make sum-of-factors a separate procedure. It's a little confusing as is, since sumOfFactors takes a single argument - and that argument isn't the number whose factors you're summing. That is:
(define (sum-of-factors n)
(define (next-perf n)
(if (= (sum-of-factors n) n)
Given that you don't want to use append, this looks great to me. I'm not sure if I can even think of a different way to do it.
My only suggestion would be naming related. l is a terrible name for a variable - it's too close to 1. orig is questionable, since it's not really the original list, it's the list you're currently "popping" (logically, not literally)...
In my opinion this is too much code for such a simple task.
Assuming that you do not have a max function, you can define it in this way:
(define (max x y)
(if (>= x y) x y))
or, if you cannot use if:
(define (max x y)
(cond ((>= x y) x)
Then, the function sosl could be defined as:
(define (sosl a b c)
(if (> a b)
Keep your concerns separated
One design principle that is vital to engineering good software is that of "separation of concerns". In other words, each function should be concerned with doing one, and only one, thing.
If you step back and take a look at the pascal function, you will see it's trying to do two things at once:
Compute Pascal's triangle
In SICP the authors note:
Count-change generates a tree-recursive process with redundancies similar to those in our first implementation of fib. (It will take quite a while for that 292 to be computed.)
On the other hand, it is not obvious how to design a better algorithm for computing the result, and we leave this problem as a challenge.
And while ...
Your algorithm is okay, but the real issue with this code is that your code style is atrocious, bordering on unreadable. Your style exhibits four main problems:
Scheme is not C, and parentheses are not curly braces. Do not put close parens on separate lines. Scheme code is intended to be read primarily by observing indentation, which brings me to the next ...
One of the ways of obtaining concision is by “astracting” a repeated operation to define a new function. For instance in this case you could use the square function previously defined in that chapter.
But if you look at the expression (square a) you will discover that it is longer then (* a a), even it is, in some sense, more readable (has a minor number of ...
As noted in the comment, your code currently looks like it has a (admittedly fairly minor) problem. In sum-multiples, you try to pass actual and limit as parameters to sum-multiples-rec, but those names aren't bound to anything at that point. You need/want something more like:
(define (sum-multiples lower-limit upper-limit)
Let's look at a simpler problem first: counting the length of a list. Here's the recursive way to do it:
(define (length lst)
(if (null? lst)
(+ 1 (length (cdr lst)))))
Okay, so, what would it look like if instead of recursing, we kept a running count of the length instead?
(define (length lst)
(length-aux lst 0))
(define (length-aux ...
That looks mostly right to me. I'll suggest two things.
First, there is nice syntatic sugar for defining functions:
(define (remove-elem xs elem)
Save yourself the lambda.
Second, you are using eq?. That is the wrong checker for this problem. That function returns true if the two objects are the exact same object in memory. It could be ...
Here are some tips that may help. Note that these are collected from feedback on #racket on irc.freenode.net (which you may find helpful too).
The length of the bytestring is counted inside the loop, but it's a loop invariant that you can hoist out of the loop.
Folding over j may be faster than mutating it as you are doing. See Mutation and Performance in ...
Well, for one thing, the python code is using a set for its amicable_pair_set, where-as you're using a large vector and setting the n'th element to n when you need to add to the set. It's a reasonable way to imitate a set, if your scheme doesn't have a set library; however, this situation doesn't need true set semantics. You can use a simple list instead, ...
The nicer way to write complement-of is with case instead of cond:
Function names generally shouldn't end in -of. (That's a way to pronounce function call, but it's not part of the name.) complement is enough. (Although some Schemes have a predefined function by ...