SICP programming study group

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
I guess i am thankful my first real exposure to programming is through Land of Lisp, i can switch between both ways of reading expressions at a very basic level only though. What kind of stuff are you studying now, if study is an appropriate word?

I'm studying IT :) As I have indicated earlier, I have been working for a long while doing pretty much all sorts of development and integration tasks you find in a SI company.

It is good you can grasps the syntax of Lisp, perhaps next you would like to think recursively for forming a linked-list ?

A -> B -> C -> D -> NULL

Would you be able to tell me how can you formulate the above linear data structure in a recursive structure ? Just for starter on what I mean by visualizing in a recurrence manner.
 
Last edited:

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
LOL it's a super bad sign that i have no idea where to begin in interpreting your question. Just not at that level yet :) I decided to go back to work on Land of Lisp where i left it halfway to see more concrete examples of programs while watching the SICP lectures at a reasonable pace. Will update weekly with my progress here if i don't have any questions or stuff to contribute.
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
LOL it's a super bad sign that i have no idea where to begin in interpreting your question. Just not at that level yet :) I decided to go back to work on Land of Lisp where i left it halfway to see more concrete examples of programs while watching the SICP lectures at a reasonable pace. Will update weekly with my progress here if i don't have any questions or stuff to contribute.

That's why data structures and algorithms are one of the core importance in understanding computer science isn't it ? No matter what methodology you have selected the core summary about computer science is the following

Apply operations on Information

How to "Apply" ? Algorithms
How to store "Information" ? Data Structures

Anything else are superfluous.

Just to encourage you on where to start

A -> (B -> [C -> {D -> NULL}])

ROOTNODE -> SUBTREE

Code:
       A   
      / \
     B   $
    / \
   C   $
  / \
 D   $
/ \
$  $

[$ is NULL]

Isn't a linked list just a lopsided binary tree ? Okay go venture then. Cheers.
 

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
I took a look at Introduction to Algorithms today and i'm afraid to say it didn't engage me. I would prefer to learn using lisp code as examples at the moment. Still, i appreciate the book recommendations and have them on my reference list :)

I actually have some questions that i wasn't able to answer on my own, do you think you could help me out if i posted them here?
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
I took a look at Introduction to Algorithms today and i'm afraid to say it didn't engage me. I would prefer to learn using lisp code as examples at the moment. Still, i appreciate the book recommendations and have them on my reference list :)

I actually have some questions that i wasn't able to answer on my own, do you think you could help me out if i posted them here?

What do you expect from an Algorithm and Data Structure lesson ? Creating websites or some immediate product ? Functional languages are largely related to recursive algorithms and recursive data structures. I can't stress more on how important it is if you want to succeed in understanding how to operate a functional language properly, if not, you at most just learn all the syntax of Lisp, but not the semantics of Lisp.

There is no shortcut if you want to talk about understanding the basis of computer science and the fundamentals. As computer scientists, we use maths and science throughout the whole computing paradigm. If you can't appreciate the beauty of algorithms and data structures, I would say you will most likely missed the whole point about learning computer science.

No matter where you start to pick up computer science, either from creating websites, creating some scripts, or picking up a language. Eventually you can't run away from Algorithms and Data structures. They form the core on how you work with information.

You can of course learn Lisp and concurrently learn about algorithms and data structures. I don't oppose that, because that is definitely a good way to get hands on and at the same time encounter difficulties in some concepts. But you can't run away from a lesson on algorithms and data structures.

Feel free to post here if you have questions. We see what we can do about it :)
 

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
I think we are coming at this from 2 different perspectives. You want me to go through the most efficient route of learning the fundamentals bottom up, while i just want to learn what happens to be capable of holding my interest, i know myself and motivation level is probably the most important thing at the moment to build up momentum :)

I will be taking 3 computer science modules next semester on real-time operating systems, software engineering and instrumentation and data acquisition. So i suppose school's good for forcing me to learn the necessary things with grades to push me, eheh.

Two things that i’m still uncomfortable with is the definition of dx as a fixed value of 0.00001, the lecturer did say this was not too important but i really would like to find an efficient definition.

The second being the definition of DF taking ONE argument of Deriv which takes an argument of the procedure for calculating the function f, then Deriv takes that function of f to calculate the derivative which requires the argument x but it isn’t too clear where the x arguments goes into DF. Is it implicit that since Deriv requires an argument x so it is legitimate to use DF with an argument x since Deriv is nested within that procedure? I hope that was the appropriate way of phrasing that question.

http://www.youtube.com/watch?v=erHp3r6PbJk
Minutes 45-50
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
I think we are coming at this from 2 different perspectives. You want me to go through the most efficient route of learning the fundamentals bottom up, while i just want to learn what happens to be capable of holding my interest, i know myself and motivation level is probably the most important thing at the moment to build up momentum :)

I will be taking 3 computer science modules next semester on real-time operating systems, software engineering and instrumentation and data acquisition. So i suppose school's good for forcing me to learn the necessary things with grades to push me, eheh.

Two things that i’m still uncomfortable with is the definition of dx as a fixed value of 0.00001, the lecturer did say this was not too important but i really would like to find an efficient definition.

The second being the definition of DF taking ONE argument of Deriv which takes an argument of the procedure for calculating the function f, then Deriv takes that function of f to calculate the derivative which requires the argument x but it isn’t too clear where the x arguments goes into DF. Is it implicit that since Deriv requires an argument x so it is legitimate to use DF with an argument x since Deriv is nested within that procedure? I hope that was the appropriate way of phrasing that question.

Lecture 2A | MIT 6.001 Structure and Interpretation, 1986 - YouTube
Minutes 45-50

I dind't go thorough with the web lectures and hence can't appreciate your question about what "dx" is unless you are talking about mathematics derivatives dy/dx. However intuitively it seems to fall under the idea of limits where Δx→0

So if you ask me, it has little to do with Lisp, which I suspect so. Indeed for discrete maths, the value of Δx wouldn't be an issue as long as it's small. The smaller, the more accurate your derivatives, unless of course you solve your derivatives using formulate eg: Given y = x^2, dy/dx gives 2x.

If what I'm describing now is what you are asking, than it brings back all the way to what I'm trying to tell you from the start of this thread. It's not the language you should be bothered with. It's the Maths, Science and so forth that you are going through which is forbidding you from understanding what course it trying to impart. This old school syllabus normally assume you have all your fundamentals on things you learn from secondary all the way to tertiary education, including quite a few more that you will normally learn in a formal computer science course. I hope you get it now.

Update: I just skim through the lecturer. If you want my most forthright opinion. I say you can give it a miss. Unless you are major in Mathematics and Science or at least extremely passionate about these subjects to the extend you can just pick up a Mathematics book and work through all the examples at the back of your brain, then you can carry on with these mode of introduction to computing. At current education system, the one I was exposed to years back, our syllabi can't even match up those few generations back, furthermore current ones. Those are the times where university students everyone look like genius in comparison to nowadays. Sorry if I have sound kinda intimidating, but I think we have quite a good number of students nowadays that enter university without a single clue why they are there in the first place, perhaps it's about getting a good hostel, hook up a nice stead and get laid. Study and intellectual commitment surely isn't one of the high priority in the students' mind. More like getting a piece of heavy weighted print certificate with their name on it. So if you still one of those geeks, nice going, I say you can carry on with these lectures.

If you are indeed searching for a good way to study computer science, my approach still stands. Learn step by step from foundation up. Learn about computer architectures, discrete mathematics, data structures and algorithms. Learn from the vast Internet with so many literatures of computing from application design and deployment, architecting, different programming languages, algorithm and data structures concepts and implementation, 3D computer graphics, Multimedia on either Video and Audio. All these are your ticket to be good in Computer Science. I can't advise you any other alternatives using current teaching methodologies that we are exposed too.
 
Last edited:

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
I think i'll keep at it :) I read somewhere the mathematical background required to understand the examples and problems shown in the lectures were to engage the students, and it's not that bad anyway. I don't mind having to refresh my math knowledge too, engineering students have to be familiar with maths like summation notation and calculus anyway. Although as i progress further, i understand at times what you mean by the difference between comprehension and realization. I need to see more concrete real world examples of programming systems being implemented to better appreciate the ideas and concepts being taught, but even then they're still interesting enough to keep me going.

If anyone is interested i got my questions answered at this online IRC: channels lisp, sicp and scheme. Other popular channels are the names of other languages like python, etc.
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
I think i'll keep at it :) I read somewhere the mathematical background required to understand the examples and problems shown in the lectures were to engage the students, and it's not that bad anyway. I don't mind having to refresh my math knowledge too, engineering students have to be familiar with maths like summation notation and calculus anyway. Although as i progress further, i understand at times what you mean by the difference between comprehension and realization. I need to see more concrete real world examples of programming systems being implemented to better appreciate the ideas and concepts being taught, but even then they're still interesting enough to keep me going.

Okay, proceed then :)
 

AnimeNewbie

Suspended
Joined
Nov 1, 2003
Messages
8,050
Reaction score
1,966
A few years back, I gave up after a few chapters of SICP though I did develop a recursive program in C++ to read all the cons cells from text file (Scheme source file). The cons recursion was driving me crazy and was very difficult to get them right.

Good luck, TS! :D
 

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
At lecture 7 and stuck. Pattern matching and rule-based substitution? I decided to go back to my former book and learn me a little more lisp before continuing :)
 

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
If anybody is studying land of lisp at the moment hit me up with a PM.. there are some portions of the code i am stuck with and i don't know how to seek help online given than people have to trawl through half the code to get to where i am to understand my problem.
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
If anybody is studying land of lisp at the moment hit me up with a PM.. there are some portions of the code i am stuck with and i don't know how to seek help online given than people have to trawl through half the code to get to where i am to understand my problem.

post the code, then explain your difficulties briefly.
 

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
(defun make-city-edges ()
(let* ((nodes (loop for i from 1 to *node-num*
collect i))
(edge-list (connect-all-islands nodes (make-edge-list)))
(cops (remove-if-not (lambda (x)
(declare (ignore x))
(zerop (random *cop-odds*)))
edge-list)))
(add-cops (edges-to-alist edge-list) cops)))

(defun edges-to-alist (edge-list)
(mapcar (lambda (node1)
(cons node1
(mapcar (lambda (edge)
(list (cdr edge)))
(remove-duplicates (direct-edges node1 edge-list)
:test #'equal))))
(remove-duplicates (mapcar #'car edge-list))))

(defun add-cops (edge-alist edges-with-cops)
(mapcar (lambda (x)
(let ((node1 (car x))
(node1-edges (cdr x)))
(cons node1
(mapcar (lambda (edge)
(let ((node2 (car edge)))
(if (intersection (edge-pair node1 node2)
edges-with-cops
:test #'equal)
(list node2 'cops)
edge)))
node1-edges))))
edge-alist))

I cannot understand what and where are the arguments coming from (node1, node2 or edge) in the lambda functions inside add-cops and edges-to-alist.

Just a guess, but the node1 seems to come from the innermost lambda that takes edge as its argument from a previously defined function direct-edges. If that is so, it's a little confusing for me..

edit: the forum dont seem to support pretty printing format, maybe it would be clearer here where the source code is
 
Last edited:

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
Code:
(defun make-city-edges ()
 (let* ((nodes (loop for i from 1 to *node-num*
                collect i))
        (edge-list (connect-all-islands nodes (make-edge-list)))
        (cops (remove-if-not (lambda (x)
                              (declare (ignore x))
                              (zerop (random *cop-odds*)))
               edge-list)))
  (add-cops (edges-to-alist edge-list) cops)))

  (defun edges-to-alist (edge-list)
   (mapcar (lambda (node1)
            (cons node1
             (mapcar (lambda (edge)
                      (list (cdr edge)))
              (remove-duplicates (direct-edges node1 edge-list)
               :test #'equal))))
    (remove-duplicates (mapcar #'car edge-list))))

  (defun add-cops (edge-alist edges-with-cops)
   (mapcar (lambda (x)
            (let ((node1 (car x))
                  (node1-edges (cdr x)))
             (cons node1
              (mapcar (lambda (edge)
                       (let ((node2 (car edge)))
                        (if (intersection (edge-pair node1 node2)
                             edges-with-cops
                             :test #'equal)
                         (list node2 'cops)
                         edge)))
               node1-edges))))
    edge-alist))

So I wouldn't bother to explain into the execution of the codes. Lambda is an anonymous function, read up at lambda - Programming in Emacs Lisp

Using the following fragment for explanation
Code:
(mapcar [COLOR="Blue"](lambda (x)
          (let ((node1 (car x))
                (node1-edges (cdr x)))
            (cons node1
                  (mapcar (lambda (edge)
                            (let ((node2 (car edge)))
                              (if (intersection (edge-pair node1 node2)
                                                edges-with-cops
                                                :test #'equal)
                                (list node2 'cops)
                                edge)))
                          node1-edges))))[/COLOR]
        [COLOR="Magenta"]edge-alist[/COLOR])

Go read up on the lisp function MAPCAR mapcar - Programming in Emacs Lisp. The first parameter is much like a C++ function reference, C you can also relate to C function pointer. The 2nd parameter is the argument for the 1st parameter of MAPCAR.

Since the first parameter of MAPCAR is substitute with a anonymous function, the parameter of the anonymous function will hence be substitute with the argument that is used for the 2nd parameter of MAPCAR. Thus edge-alist is the argument for parameter "X" of the anonymous function.

In Javascript, you can envision as
Code:
mapcar(new function(X) { ..... }, [1,2,3,4,5]);

function mapcar(func, list) {
  var outlist = [];
  for (var i = 0; i < list.length; i++)
    outlist.push(func(list[i]));
  return outlist;
}
 
Last edited:

Synasta

Junior Member
Joined
Nov 21, 2010
Messages
40
Reaction score
0
Hi, thanks for taking the time to answer my question, and sorry for the late reply as i have been caught up in schoolwork. My question is with the edges-to-alist function, i don't know in what sequential order the code evaluates. Please correct me if i'm wrong:

First,

(remove-duplicates (mapcar #'car edge-list))))

creates a list of nodes from the argument edge-list. This evaluates the edge-list

from

((25 . 2) (2 . 25) (22 . 19) (19 . 22) (7 . 17) (17 . 7) (21 . 16) (16 . 21) (11 . 22) (22 . 11) (29 . 2) (2 . 29) (21 . 29) (29 . 21) (27 . 8) (8 . 27) (13 . 29) (29 . 13) (5 . 16) (16 . 5) (27 . 4) (4 . 27) (28 . 25) (25 . 28) (25 . 11) (11 . 25) (6 . 2) (2 . 6) (12 . 17) (17 . 12) (17 . 10) (10 . 17) (15 . 7) (7 . 15) (7 . 18) (18 . 7) (17 . 15) (15 . 17) (16 . 30) (30 . 16) (12 . 26) (26 . 12) (19 . 29) (29 . 19) (24 . 5) (5 . 24) (10 . 16) (16 . 10) (13 . 9) (9 . 13) (15 . 8) (8 . 15) (3 . 4) (4 . 3) (8 . 9) (9 . 8) (14 . 1) (1 . 14) (28 . 10) (10 . 28) (12 . 28) (28 . 12) (22 . 3) (3 . 22) (5 . 19) (19 . 5) (26 . 16) (16 . 26) (23 . 1) (1 . 23) (23 . 12) (12 . 23) (29 . 25) (25 . 29) (30 . 28) (28 . 30) (30 . 15) (15 . 30) (8 . 5) (5 . 8) (19 . 7) (7 . 19) (9 . 22) (22 . 9) (7 . 21) (21 . 7))

to a result of

(27 11 6 2 18 17 24 13 4 14 10 3 26 16 1 23 12 29 25 28 30 15 8 5 19 9 22 7 21).

Second, we create a new list using

(remove-duplicates (direct-edges node1 edge-list)
:test #'equal)

which is a function for creating a list of the edges which look like something like this (for a node of 17):

((17 . 7) (17 . 12) (17 . 10) (17 . 15))

though i am not too sure why remove-duplicates is necessary as i have not seen any case where there are duplicate pairs.

Next, we mapcar the function (lambda (edge) (list (cdr edge))) over each of the cons pair and retrieve a nested list of connecting nodes to the node (17 in this example)

((7) (12) (10) (15))

Finally we construct the alist using cons to link a node with its connecting nodes for every node from the list

(remove-duplicates (mapcar #'car edge-list))))

Sorry if it seems overly detailed, most of writing this out was clarifying for my benefit :) Did i get the sequential order right?

Could you tell me how you paste the code with black background and pretty printing?
 

davidktw

Arch-Supremacy Member
Joined
Apr 15, 2010
Messages
13,546
Reaction score
1,299
Hi, thanks for taking the time to answer my question, and sorry for the late reply as i have been caught up in schoolwork. My question is with the edges-to-alist function, i don't know in what sequential order the code evaluates. Please correct me if i'm wrong:

Functional languages uses lazy-evaluation, while imperative languages, most if not all, uses eager evaluation.

This means given the simple example below,
Code:
f(g());
Imperative languages such as Java, C/C++, Perl, PHP, Javascript, Ruby and a lot more will first evaluate 'g()', then pass it's result to f() as argument for evaluation.

Functional languages lazy evaluation works different. In sequence nature, you will find f() is evaluated first. Function g() is never evaluated until its evaluation is required inside f(). That's why for some recursive functions, functional languages can evaluate faster given lazy evaluation helps to prune evaluation tree nodes.

If my 'f' function is pseudo declared as such
Code:
f(var g) {
  if (0 > 1) {
    g();
  }
}

f(h());

You will find h() is never evaluated for functional langauge, so even if h() has an infinite loop, functional language will be able to evaluate f(), but for imperative languages, it has to first evaluate h() first, which will crash with a "out of memory", or "out of stack space" error.


First,

(remove-duplicates (mapcar #'car edge-list))))

creates a list of nodes from the argument edge-list. This evaluates the edge-list

from

((25 . 2) (2 . 25) (22 . 19) (19 . 22) (7 . 17) (17 . 7) (21 . 16) (16 . 21) (11 . 22) (22 . 11) (29 . 2) (2 . 29) (21 . 29) (29 . 21) (27 . 8) (8 . 27) (13 . 29) (29 . 13) (5 . 16) (16 . 5) (27 . 4) (4 . 27) (28 . 25) (25 . 28) (25 . 11) (11 . 25) (6 . 2) (2 . 6) (12 . 17) (17 . 12) (17 . 10) (10 . 17) (15 . 7) (7 . 15) (7 . 18) (18 . 7) (17 . 15) (15 . 17) (16 . 30) (30 . 16) (12 . 26) (26 . 12) (19 . 29) (29 . 19) (24 . 5) (5 . 24) (10 . 16) (16 . 10) (13 . 9) (9 . 13) (15 . 8) (8 . 15) (3 . 4) (4 . 3) (8 . 9) (9 . 8) (14 . 1) (1 . 14) (28 . 10) (10 . 28) (12 . 28) (28 . 12) (22 . 3) (3 . 22) (5 . 19) (19 . 5) (26 . 16) (16 . 26) (23 . 1) (1 . 23) (23 . 12) (12 . 23) (29 . 25) (25 . 29) (30 . 28) (28 . 30) (30 . 15) (15 . 30) (8 . 5) (5 . 8) (19 . 7) (7 . 19) (9 . 22) (22 . 9) (7 . 21) (21 . 7))

to a result of

(27 11 6 2 18 17 24 13 4 14 10 3 26 16 1 23 12 29 25 28 30 15 8 5 19 9 22 7 21).

Looking at
Code:
(mapcar #'car edge-list)

For the illustration I'm giving below, download a clisp interpreter and try it out.

Given that 'edge-list' is a generic list. Each element in the list is also a list. What 'mapcar' is apply the function 'car' onto each element in the list and produce another list.

When we use (car '(25 2)) ==> 25. 'car' evaluate to be the first or head element of the list. If you apply it to the list above each element by a time, you get
Code:
(25 2 22 19 7 ... 9 22 7 21)

That is exactly evaluated by 'mapcar', applying the mapping function, in this case 'car' onto each element of 'edge-list'

After that, 'remove-duplicates' merely remove duplicates elements from the list. I believe this is straight forward.

Second, we create a new list using

(remove-duplicates (direct-edges node1 edge-list)
:test #'equal)

which is a function for creating a list of the edges which look like something like this (for a node of 17):

((17 . 7) (17 . 12) (17 . 10) (17 . 15))

though i am not too sure why remove-duplicates is necessary as i have not seen any case where there are duplicate pairs.

You did not provide the source for 'direct-edges', hence I wouldn't be conclusive here.
I will not assume edge-list to be unique, and hence remove-duplicates makes sense to be used.
Just because your use-case doesn't have duplicates doesn't mean it is not justified to use 'remove-duplicates'.
You can only justify if it is required after you can confirm the input list will never have duplicates.

As if any defensive programming, I will recommend unless you can control the input list.

Next, we mapcar the function (lambda (edge) (list (cdr edge))) over each of the cons pair and retrieve a nested list of connecting nodes to the node (17 in this example)

((7) (12) (10) (15))

Finally we construct the alist using cons to link a node with its connecting nodes for every node from the list

(remove-duplicates (mapcar #'car edge-list))))

Sorry if it seems overly detailed, most of writing this out was clarifying for my benefit :) Did i get the sequential order right?

I am kinda lost here, since I have no prior knowledge to what is going on.

Could you tell me how you paste the code with black background and pretty printing?

I uses VIM's indentation feature to do it for me. You can use any editor that can pretty tidy
up certain functional languages syntax. It will look pretty similar

Black background with colouring is
done via this forum's markup as shown in the image below
1621ywy.png
 
Important Forum Advisory Note
This forum is moderated by volunteer moderators who will react only to members' feedback on posts. Moderators are not employees or representatives of HWZ Forums. Forum members and moderators are responsible for their own posts. Please refer to our Community Guidelines and Standards and Terms and Conditions for more information.
Top