3 ms·
Take a look at this sample from wikipedia: (defun factorial (n) (if (<= n 1) 1 (* n (factorial (- n 1))))) Now imagine trying to explain that
by markessien 18y ago
Take a look at this sample from wikipedia:
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
Now imagine trying to explain that to a person who does not use a computer. Humans always start learning by looking for the objects, then applying an action on the object. With lisp, this object is not obvious, and the actions being applies are not obvious either.
- utx00 18y agoare the axioms of non-euclidean geometry obvious? what about special relativity?
- markessien 18y agoYou are saying that I am using the solution for a tough problem as being representative of the use of the language? That may be so, but what I was pointing out was how different they language structure was from traditional human languages.
- utx00 18y agothey are different domains of expression. so that should not come as surprise. maybe one day when computers are super powerful. for now "code is data and we write in the same data structures the compiler understands" seem like the bigger win. that of course means a lisp of some sort.
- fauigerzigerk 18y agoI never found this objects first idea very plausible. It's just OO dogma, not cognitive science. Which of the following expressions is most "natural" in your view? person.buy(house, agency, contract) agency.sell(house, contract, person) house.sale(person, agency, contract) contract.fulfil(house, person, agency) Of course the decision is not taken based on what's easiest to explain to non computer users but rather on which object's encapsulated data is most affected by the operation, or which inheritance hierarchy should be used to look up the operation. In most non trivial cases that's extremely subjective. Being forced to make that decision _every time_ you call or write a function is a complete waste of intellectual effort. Since there is always one name for what should happen (the name of the function) but potentially many objects that are involved in some capacity, it seems much more consistent to give a special syntactical place to the function rather than to any of the objects: sell(house, person, contract) or if you prefer (sell house person contract)
- markessien 18y agoI'm not directly arguing for OO. In my opinion, a good language is one which forces the black box encapsulation of complex behaviour. 'House' as an abstraction for a house is a good model. Performing an action on an abstraction should be in an intuitive manner, for example: sell House That's pretty clear. To cause the interaction between two objects, then one should place the action between the objects: make "Agency" sell "House" where 'make' is equivalent to calling a function. Now, let's bring in a contract make "Agency" sell "House" using "Contract" this OO model works in my opinion because there is one path between the objects, and the arguments describe the contents of the path. make "Person" buy "House" using "TerribleContract" I believe that programming languages are too flexible. I believe that programming languages should be constructed in a manner that forces you to abstract complex structures into aggregates of behaviour, where the input to these aggregates consist of a very low number of paths. Java, C+++ fail in this in that they allow you to break out of the abstraction hierachy. They allow you to have callbacks and inheritance and so on, which breaks the black-boxiness of your program. A black-box should always take the same inputs and should always produce the same behaviour from those inputs. Now, what about other types of programming constructs? Let's say I wanted to send a file to another PC using sockets: create "File" using "/hello.txt" As the next step I'm trying to open a port. However, a port has a number. I could try to do this: create "Socket" using ("Port" using 8934) "Port 8934" is something that can be merged together into a composite structure and so the user should be forced to do so: "InputPort" is "Port" using 8934 create "Socket" using "InputPort" make "Socket" send "File" destroy "Socket" This is an example of how I think a properly abstracted language should look like. Force single paths to all abstractions, and force abstraction use.
- whacked_new 18y agoIsn't the abstraction, and sticking to the abstraction, the job of the programmer, and not the language? We all speak English here; you can say, "let's all speak like Yoda now." Quite easy, that is. But the underlying language doesn't need to change; other people can invent different rules and create different settings where these rules apply strictly. So imperatively, your socket program is like this: f = file("/hello.txt") p = makeport(8934) s = makesocket(p) s.send(f) s.destroy() which is perfectly fine. This is basically a line by line translation from your English-looking pseudocode to this OO-code-looking pseudocode. Using s-expressions would make the whole process read much more like speaking: Let's say I wanted to send a file: Using the socket that uses the port 8934, send the file hello.txt, and destroy the socket. Plain English, right? Reorder into: Destroy the socket that is used to send the file hello.txt and is created with port 8934. Translate to s-expr: (destroy-socket (send-file (make-file "hello.txt") using (make-socket (make-port 8934))) I'm taking liberties with the send-file function syntax. Looks ugly, but that's pretty close to the natural language representation. If you parse the syntactic tree it will almost overlap completely.
- whacked_new 18y agoSure, lisp syntax is itself not intuitive, but I was pointing out that the reasoning involved in lisp programming does not clash with how humans are wired. It could clash with how humans are trained, but inherently, s-expressions are a good representation of human speech.
- jimbokun 18y agoIf the person knows the mathematical meaning of factorial and the underlying concepts, this will be very easy. If not, this will be really hard using any programming language.