marick / fp-oo Goto Github PK
View Code? Open in Web Editor NEWCode samples and exercise solutions for /Functional Programming for the Object-Oriented Programmer/
Code samples and exercise solutions for /Functional Programming for the Object-Oriented Programmer/
When doing the Ex. 16.5.5 I was confused on which element the new state's map was going to replace...
For example, the following monadic value map:
{:state stateVal, :result result}
should entirely become a new map or should be redefined just stateVal as a map? (It turns out it is the latter).
A hint like the following could help:
(map? {:state stateVal}) must be true
They're not used in the G release
It's the one about call-super.
It shouldn't be deleted from the exercise solutions until the G release.
in the example for def result
, do-monad
should be domonad
on page 166 of gastropod,
(do
(expect (+ 1 2) => 3)
(expect 3 => old?))
surely that's gotta be odd?
It's hard to remember what :__own_symbol_
is for. Would the above name change help?
You say
Suppose you wanted to set an atom’s value to 33. How would you do that? Keep in mind that swap! demands a function, not (say) an integer.
I assumed I just had to add 32 to the current number of 1, so I just did (swap! my-atom (partial + 32))
. Only after reading the next exercise did I realize your true intention. I guess what's not clear is when you say "an atom" you mean any atom, not the one just referenced in the example code.
Hi,
in chapter 10.9's exercise, we need to use nomads library:
`(use 'clojure.algo.monad)
When trying to run it in lein , It has an error that it can't the class:
user=> (use 'clojure.algo.monad)
Execution error (FileNotFoundException) at user/eval2792 (REPL:1).
Could not locate clojure/algo/monad__init.class, clojure/algo/monad.clj or
clojure/algo/monad.cljc on classpath.
⇒ lein -v
Leiningen 2.9.1 on Java 1.8.0_172 Java HotSpot(TM) 64-Bit Server VM
e
Anyone has an idea?
(couldn't find anything in Google)
Thanks
The class-from-instance
function gets used on page 55 but it hasn't been explained yet. A little confusing and I had to find it in this repo in order to keep running the code along with the book. I think it was a helper function you extracted from send-to
in 5.4 exercise 1, but that wasn't referenced in the book.
Similarly, page 56 introduces the lineage
function, and it seems like that's not defined until page 66. It might be worth making some kind of note to the reader that this is just dream code that will get fleshed out later. I tend to follow along with the code and use the REPL to make sure I understand what's going on with your examples, and that approach stopped working in the beginning of this chapter.
The chapters do refer to the names of the source & solutions files - but perhaps they could be named simply for the chapter they are for?
The text says you want to replace (*) expressions with a more complex expression, but the code replaces (-) expressions. The part that is underlined with ^^^^^ just seems entirely incorrect. e.g. Where did those 55555s come from?
There's this line right after exercise 5 of chapter 5:
o# Inheritance (and Recursion) {#inheritance}
Guessing that was supposed to be parsed?
send-super
can only be used once. That is, the method called by a send-super
cannot itself use send-super
. The reason is that the method does not know which class it belongs to. To fix this, send-super
would have to take an owner
argument as well as a this
argument. Dunno if that's worth it.
Note that the current implementation doesn't work at all once you introduce modules.
On fastidious flounder, page 149 of the PDF version, you correctly say:
You’ll have to be sure to use that first line (the use statement) in your repl.
I'd also write a note about:
[BTW, on page 148 do-monad should be domonad]
(with-monad sequence-monad
(domonad [a [1 nil 3]
b [-1 1]]
(* a b)))
Returns:
NullPointerException clojure.lang.Numbers.ops (Numbers.java:942)
And not, as suggested on 16.4 Exercise ("fastidious flounder" version):
` (-1 1 nil nil -3 3)
the book says to clone this repository and run lein midje - this no longer works as of 2/16/2022. Because the default lein install is for version 2, I had to cobble together my own path to getting the midje checks to pass - mostly amounting to putting the latest version of midje in the user profiles.clj and updating the midge dependency in the downloaded repo project.clj to 1.6.0. Once I did those things, it showed some 1200 checks passed. Considering the book is still available and gives a suggested price of $20 which I paid, it seems like keeping the basic getting started up to date might be worthwhile. I would include a pull request, but a) it requires an update to the book or comment on the purchase page, and the change to this repo is pretty tiny if someone does decide to take it on.
Apologies if this is too superficial at this stage, but it's a bit annoying when the links don't work.
Not sure whether you want the raw listings or not, since it varies. I'm assuming here that you wanted the regular link with syntax highlighting.
3.4
Sources link points to raw but broken https://raw.github.com/marick/fp-oo/master/add-and-a.clj ; should be regular https://github.com/marick/fp-oo/blob/master/sources/add-and-a.clj
Solutions link points to regular.
4.1
Sources link points to raw embedded-functions.clj.
Solutions link points to regular just-enough-clojure.clj ???
5.4
Sources link points to raw.
Solutions link points to regular.
Exercise 5: superclass link points to broken https://github.com/marick/fp-oo/blob/master/solutions/sources/superclass.clj ; should be https://github.com/marick/fp-oo/blob/master/sources/superclass.clj
Also the link text says source/superclass.clj, should be sources/superclass.clj.
5.10
Sources link points to raw.
Solutions link points to regular.
Exercise 2: superclass link points to raw
6.4
Sources link points to raw.
Solutions link points to regular.
7.9
Sources link points to raw.
Solutions link points to regular.
10.4
Exercise 5: without-klass link points to broken https://raw.github.com/marick/fp-oo/master/sources/without-class.clj ; should be https://github.com/marick/fp-oo/blob/master/sources/without-klass.clj
Exercise 9: higher-order-functions link points to raw.
11.9
Sources link points to raw.
Solutions link points to regular.
Object result = f.invoke(restructureCoursesList(courses),
restructureSignups(registrant));
should be
Object result = f.invoke(restructureCourses(courses),
restructureSignups(registrant));
Version: discursive-diplodocus
Page: ii
The word "this" is superfluous in "[...] but this these chapters focus on it explicitly [...]".
For the garrulous gastropod version:
Section 10.8, para right after code, "Given a pair, cond evaluates its element." I would think you would want to say "... cond evaluates it first element".
Section 11.8, page 166, "... either left-hand or right-hand size of an arrow." You must want "side", not "size".
Section 15.5, page 236, "... to be passed to in as the source-monad:", probably want to be "to be passed in as the source monad:".
Same page, toward the bottom: "... fair amount of rote code and a core of core that requires" might want to lose "of core".
I realised Exercise 1 was a problem with certain methods not being in the method cache, but thought the task was to fix the functions building it (like method-cache) or accessing it (like apply-message-to or send-to).
Giving up, I looked at the answers and realised the solution was to rewire the (super)class relationships. It would have been helpful to know that was what we were meant to do from the start (and that we had permission to do so in producing a solution).
I also found the end result of those answers counter-intuitive (as reflected by your diagram in Exercise 3, which is fine). My natural inclination was to think of MetaAnything as being at the top of the hierarchy. Instead, MetaAnything's superclass (Anything) is an instance of itself. Was that bizarre result intended?
See https://twitter.com/alindeman/status/254595769947013120
and
https://gist.github.com/3845119
Be sure to credit Andy Lindeman
Version of the book:
discursive-diplodocus
Just bought the book and started reading. But now I'm stuck.
Paragraph 1.1 says:
The easiest way to install and run clojure is through Leiningen. Go to its page and follow the installation instructions.
I have a MacBook Pro model late 2011, OS X 10.7.4.
I'm an experienced Windows programmer (20 years), my main language is C# now, I have a mac since 6 months, but I can't get this to work.
I followed the instructions on the https://github.com/technomancy/leiningen page.
I've just installed github for mac, I was able to do "Clone in mac", I have the repository downloaded in my documents folder.
But now I go to /leiningen/bin and want to start the lein executable.
This is what happens:
/Users/wouter/Documents/leiningen/bin/lein ; exit;
wouters-MacBook-Pro:~ wouter$ /Users/wouter/Documents/leiningen/bin/lein ; exit;ls: /Users/wouter/Documents/leiningen/leiningen-core/lib/*: No such file or directory
Leiningen is missing its dependencies.
Please see "Building" in the README.
logout
I don't understand this part either:
$PATH
. (I like to use ~/bin
)chmod 755 ~/bin/lein
)I understand step 1, but I figure it's not necessary because I have done the git clone already.
I don't understand step 2 and 3.
If I want to do something with path on my mac (I know how it works on Windows), I find this page:
http://stackoverflow.com/questions/135688/setting-environment-variables-in-os-x
and it doesn't clear anything up...
When I "get the standalone jar from the downloads page" and execute it, I get an error "The Java JAR file "leiningen-2.0.0-preview10-standalone.jar" could not be launched. Check the Console for possible error messages."
The error message in the console is:
[0x0-0xeceece].com.apple.JarLauncher[11011]: Failed to load Main-Class manifest attribute from /Users/wouter/Downloads/Leiningen-2.0.0-preview10-standalone.jar
I'm sure there are other easy ways to install clojure on my mac if I google a bit, but I wanted to let you know about this.
- When viewing the image in section 11.4 in iBooks on an iPad 2, the "The FUNCTION +" unfortunately looks like "The FUNCTION -", which could be confusing. I see that it is correct in the PDF, so it must be a scaling artifact when reducing the size to fit on the screen.
I'll check if that happens on an iPad 1. If so, I'll see if I can fiddle around with the size of the source .png, but that'll happen later.
Happy to read the book!
On p.114 (published 2012-10-17), you use the example:
(comp not not predicate)
As I understand, boolean
does the job:
(comp boolean predicate)
It might be worth changing the example or at least noting this, lest it give the impression that inelegant Clojure code is needed here.
Apparently Clojure does not work so well as soon as you put dashes into your file names.
To me it is kind of confusing that many files contain dashes given that you are aware of this "problem" (you are, aren't you?)
Do you have any explanation for that or a workaround to require files with dashes in them?
(require 'my-solutions.add-and-a)
=> java.io.FileNotFoundException: Could not locate my_solutions/add_and_a__init.class or my_solutions/add_and_a.clj on classpath: (NO_SOURCE_FILE:0)
Version: descriptive-diplodocus
Page: 13
After introducing the user to the new function (fn [n] (+ n n))
on page 12, the first example box on p.13 contains (+ 2 n)
as function body which may interrupt the reader's flow.
There are some functions in the object system implementation that take maps, some that take symbols. Sounds like a job for generic functions.
I think I had a reason for that (to introduce or
?) but I forget what it is and I don't think it makes sense.
Supposedly replicate
is deprecated in favor of repeat
(according to doc
)
They've been replaced with add-and-make.
Hi,
I've just started looking at this and I thought I'd pass on my thoughts on Section 1 since the start of book like this is very important. For background I'm a long-term (15+ years) C++ programmer with no experience of functional programming.
BTW I'm enjoying the book so far!
Section 1.6 (minor)
Found myself asking; What happens if repl given "(+ 1 - 3 2)" instead of "(+ 1 (- 3 2))". Would "1 - 3 2" be passed to '+' function? i.e. does + takes 2 parameters or a list?
Section 1.9 (minor)
What are 'def'? A symbol?
Likewise, what is 'twice'?
Section 1.16 (major)
Considering the number of pages to section 1.6 (something familiar to most programmers), this is very short for a complex (and novel to an OO programmer) example. Understanding this section I feel is key to understanding the general approach to solving the excercises. It's a different way of thinking about problems. I think there should be some text before all these details about how Clojure works to explaining something the different mindset of functional programming. Otherwise its difficult to approach the examples since all the reader has is an OO way of problem solving, but some basic Clojure syntax.
Section 1.17 (medium)
You don't really say what the map function does (have to work it out). Something like
"The map function is perhaps the most common loop-like function. (If you know Ruby, it’s the same as collect.) [say
what map does here]. For example Clojure has an inc function that returns one plus its argument."
Section 1.18 (minor)
In LightTable I get
"(doc filter) => java.lang.RuntimeException: Unable to resolve symbol: doc in this context, compiling:(NO_SOURCE_PATH:25:2)"
Typo
Warning: I’m using to using load in other languages, so I often reflexively use it instead of loadfile.
That leads to this puzzling message
In "The Trickiness of Removing" on page 169 of the PDF version of Ecstatic Earthworm, there is either an error in the text or I am confused about what you are trying to convey:
Remember that zip/next moves depth-first, not breadth-first. The next node after (+ 1 HERE) is 1, not (2 3).
From the example that is in play, I would expect this to say "The next node after (+ 1 HERE) is +, not (2 3)." since the depth-first walk would take you into the seq at the left-most position. I've confirmed this with the REPL:
user=> (def zipper (zip/seq-zip '((+ 1 HERE) (+ 2 3))))
#'user/zipper
user=> (-> zipper zip/down zip/node)
(+ 1 HERE)
user=> (-> zipper zip/down zip/next zip/node)
+
This is using the original zipper, not the one resulting from the removal, but I see the same thing with the latter as well.
My first read-through of Chapter 8, "Embedding Functional Code in an OO Codebase", garrulous gastropod, I finished reading the chapter with the impression that the introduction mentioned 2 approaches and the chapter only described 1.
Closer reading revealed that approach 2 ("OO coating around a gooey functional center") is mentioned almost as an aside in the conclusion of the chapter.
It would be interesting to see this given the same weight as the first approach ("chunky functionalism"), as well as some text putting these approaches in the context of the leading practices of object-functional languages like F#, OCaml, and (of course) Clojure. What do people end up doing when mixing OO and FP is nearly frictionless?
Is there any extant code in non-object-functional, but rather object-oriented, languages that you'd recommend reading as a good demonstration of this style?
As I understand, a manager can't participate in afternoon sessions.
I understand the solution suggested at https://github.com/marick/fp-oo/blob/master/solutions/scheduling.clj
The logic is when checking availability.
But what if we pass the manager boolean to solution function ?
Something like that:
(def separate-1
(fn [pred sequence]
[(filter pred sequence) ()]))
(def solution
(fn [courses registrants-courses instructor-count manager]
(map (fn [courses]
(half-day-solution courses registrants-courses instructor-count))
(if (true? manager)
(separate-1 :morning? courses)
(separate :morning? courses))
)))
(the reason for separate-1 is because I couldn't do filter in the if clause. Got a null pointer exception.
Did I miss something?
I am part way through the book and enjoying it very much. Here are the things I have noticed.
Comments on FP-OO (version G)
p27: (One or more semicolons starts a comment.
p23 or so: If you know Ruby, map is the same as collect.
p29: Note: if the problems you think of...
p40: Here's a less boring method: shift
p49: So Clojure provides an alternate way to name sub-computations.
p57: I would prefer getting an exception over getting a nil.
p69: ...it passs a partial solution down the levels...
p76: Section 6.5 "Finishing up"
p93: There's little of interesting remaining.
p94: There you have it: a pretty functional solution to our problem.
p96: If you’d like to examine this solution in more detail, see sources/wrapped-scheduling.clj
General comment:
p103: Here's a sequence of maps:
p106:
p107: whether it be handled with objects or not
p110: complement would be easy enoguht for us to define:
p115: Exercise 2 -- your output is [false (:c :b :a) 3], but I get mil instead
of false
p117: Exercise 9 -- the calculation is supposed to be for [4 8 9 3 2], but it's
actually for [4 8 9 4 2].
p117: Implement check-sum and upc? and check it against these numbers (also in the sources):
p118: In object-oriented programs, It’s not horribly unusual
p121: unnecessary page break
The text for the link says "solutions/embedded-functions.clj" but the link and the footnote go to https://github.com/marick/fp-oo/blob/master/solutions/just-enough-clojure.clj
Check after my machine stops being borked.
I found a small improvement regarding
The Elements of Functional Style
Basic Datatypes that Flow through Functions
Processing sequences of maps
chapter from the "garrulous gastropod" version:
the "separate" function actually does exist, although not in the core language,
but in the clojure-contrib library.
("Inexplicably, Clojure doesn’t have a separate-by-predicate function").
I stumbled on this by typing the following in lighttable (the recommended IDE):
(separate odd? [1 2 3 4 5 6])
and obtaining the actual result: [(1 3 5) (2 4 6)]
.
Add a mention that the "separate" function is available through the clojure-contrib library (which lighttable probably uses).
Check that the "up" and "left" pointers for the sources and solutions are consistent with the text. Some of them may have been corrected in only one place.
I realise you're not too interested in typos, but some readers might be confused.
In the first hint for exercise 4 in 5.4, the first set of {} should probably be ().
Given that lists are seqs, but are not lazy, should I use "lazyseq" consistently throughout?
(perhaps others as well - but this is the first that i noticed)
exercise #5 asks the reader to predict the outcome. I think it might be nice to include a short comment in the solutions file explaining what the result actually is. While it is easy to run the code; relying upon that presumes that the reader's code is functioning the same as the authors at that point.
I'm not sure what the exercise in 4.1 is asking me to do:
"Change the Point constructor to add x and y accessors."
What is an accessor? Is it like a 'get' method? Why would I need it if I can just use :x on a Point directly?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.