Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
As the title says, what's the appeal of LISP?
I've seen it raised to high heavens and back and then put on a pedestal over an over. I've seen it done by by people here, by actual programmers that I know, by university professors that try to look like the kind of enlightened guys who have obviously transcended the plebeian language-war and would rather die than commit the heresy of saying that one language is better than another.
I tried to learn it, I looked at a few tutorials, at the "learn x in y minutes" page for both lisp and clojure(since from what I understand it's lisp running on the jvm with more FP thrown in), and I understand the syntax and how to do stuff in it. And I went back to tutorials about it several times over the last few months but every time the syntax made me want to look for a high-school kid and yell at him for messy code because looks like a C-style if-condition gone wild with all the nested parentheses and simple things seem to become a chore. What lisp seems to do in a few lines, other FP languages like Haskell or F# or even non FP languages like C# who just discovered that map and filter are a thing seem to do in much less in a much more expressive way.
Am I looking at this wrong?
Is there some click that needs to happen?
Did I only find crappy resources?(if yes please give me some good resources for learning lisp/clojure, preferably with some exercises)
What in the ... is the appeal of lisp? Honest to God question here.
Thank you in advance!
When I first heard about Clojure in 2009, I wrote a blog post titled "Clojure: Where's the Elegance?" I was a big fan of Python's style of elegance at the time ("executable pseudo-code"), and Lisp was deeply unfamiliar. I continued wrestling with Clojure, though, because "list processing" seemed like an important programming paradigm to have in my toolset. I used a lot of JavaScript, Ruby, and C# for a while, and on my own time played with ClojureScript. When I finally came back to Python in 2017 to do some data-munging, I discovered I was writing a lot of Clojure-inspired functions to help. Finally, I just started writing the data-processing in Clojure, and I wouldn't go back. So while you've asked a question that may not be answerable, perhaps I can shed some light on what accounts for the difference between your perspective and the enthusiasm of the Lisp community.
First, while Lisp is very alien coming from the rich grammars of C, Python, and Ruby, the lightness of Lisp's syntax turns out to be a tremendous blessing. It relieves a lot of cognitive burden. Many kinds of syntax errors completely disappear. But by far the most good I get out of Lisp's consistent grammar is how easily it can be transformed. What I miss most when working in other languages is the ability to rearrange the AST without having to fiddle with the actual text of the code. Working with Lisp is far more fluid than any other language I've experienced.
Second, it's trivial to control how code is evaluated. A lot has been written about the glory of macros, but to me the fundamental superpower is that you can prevent code from being evaluated, evaluate it in a specific order, or evaluate it multiple times, all without the syntactic overhead of wrapping that code in a function. That said, I don't write macros very much, but when I do, a function is a poor substitute.
Third, most languages don't have very good support for live coding. I typically don't use the REPL itself, but rely on an editor integration to evaluate code. Clojure's tooling is good enough that I can mold an entire codebase with dozens of namespaces without ever having to restart the JVM process or split a single big code file into separate modules.
Fourth, Lisp code tends to compose extremely well. Between everything being an expression that returns a value and the language being built on a relatively small set of data structures, you can mix and match language constructs with great liberty. That opens up a lot of possibilities where other languages put up walls.
The common factor of all these is that the language does its best to get out of your way. When I was a novice programmer, the complex grammars of C and Python and Ruby was an aid to programming. It kept me on the straight and narrow. The language constructs were like landmarks to navigate by. Lisp, without those landmarks, can feel like a foreign country. But as you get more familiar with Lisp, other languages feel artificially constraining and hard to move around in, like driving on roads when you could be flying. Lisp is very freeing, but from my personal experience, I can tell you that, like flying, it takes practice before the strangeness of it turns from fear to freedom.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I would like to write a simple in-house program that parses user commands written in a language of our team's own invention (but based closely on another program we are already familiar with). The command parser that I am working on now will simply be the UI through which the user can run the other algorithms I have already written. (Those other algorithms, by the way, are used to generate the input files for a molecular dynamic simulation package called LAMMPS.) The only thing I really have left to do is just write this UI, but as it turns out, writing your own scripting language is almost an intractable challenge for a non software engineer to tackle on his own.
According to the answers I received, what I am try to make would be considered a Domain Specific Language, and it is not advisable to try to make one's own DSL due to the enormous amount of work required to make it useful and bug-free.
The best option then would actually be to use an existing scripting language like Lua or Python, and embed it in the program.
To do this, I will most likely use Lua because it seems most fitting for our needs. So at this point, the rest of this question is no longer relevant since the answer would be: "Don't do it yourself." But I'm still going to keep part of it here for other users to be able read and learn from the wonderful answers below.
Thanks again to everyone who replied!
Old Question:
I would like to write a program that parses a user text input and then
runs a function corresponding to that input. To do this I would need
to parse the string for relevant keywords. I believe there will be
less than 15 keywords when I'm done, so ideally I'd like this code
to be simple and short.
The problem is that I am currently using if-statements to parse the
strings. This is an extremely inconvenient way to parse commands
because even for a short 3 word commands the code explodes into nested-ifs
3 layers deep. So longer 8+ word sentences will become nested-ifs more than
8 layers deep.
This kind of programing approach quickly becomes unmanageable, especially
when I need to make any significant changes to a command.
My question is whether or not there exists a data structure in C++ that
can help me better manage my giant nested-ifs, or if anyone could suggest
a better way to parse a string for lots of different data types (i.e.
substings, ints, and floats) and output an error message when the expected
type is not found?
Here is an example of a short user session to show the kinds of commands
I would like to interpret:
load "Basis.Silicon" as material 1
add material 1 to layer 1
rotate layer 1 about x-axis by 45 degrees
translate layer 1 in x-axis by 10 nm
generate crystal
These commands are based on an already-existing program that our team
uses, but unfortunately the source code for this program has never been
publicly released so I am left guessing as to how it was actually
implemented.
One final note, unlike natural language processors, I know exactly what
the format of each line will be. So my issue isn't so much how to interpret
the text, but rather how to code the logic in a concise and manageable way.
Thanks everyone!
Your question is not clear. And your goals are more difficult than what you believe.
Either you consider that you want to somehow process human language sentences (e.g. in English). Then you want to study natural language processing, and you can find some libraries related to that field.
Or you consider that you want to interpret some formal programming or scripting language. Then you want to study interpreters and compilers. BTW, in that case, you might just embed an existing interpreter (like Lua, Guile, Python, etc....) in your program.
You could also think in terms of expert systems with a knowledge base made of rules (this approach could be viewed as in the middle between NLP and scripting language) You'll then need some inference engine (perhaps CLIPS). See also J.Pitrat's blog.
Notice that even coding a simple interpreter is more difficult than you believe. You absolutely need to represent abstract syntax trees, which you construct from textual input with a parsing phase.
BTW, All of NLP, expert systems, and interpreter design and implementation are difficult fields. You could get a PhD in all 3 fields (but you have to choose which).
If you go the embedded interpreter way: study the interpreters I mentioned (Guile, Lua, Python, Neko, etc...) and choose which one you want, to embed.
If for whatever reason, you want to make an interpreter from scratch: Learn several programming languages first (including scripting languages like Ruby, Python, Ocaml, Scheme, Lua, Neko, ...). Read books on Programming Language Pragmatics (by M.Scott) and Lisp In Small Pieces (by Queinnec). Read also text books on compilation and parsing, and on Garbage Collection and formal (e.g. denotational) semantics. All this may need a dozen years of work.
Notice that by experience embedding a software in an interpreter is a very structuring design. If you did not thought of that at the beginning you probably need to redesign and refactor a lot your existing application. For instance, when embedding a software in an interpreter, you cannot afford that bad input crashes the program. So error handling and memory management (interfacing to the GC of the interpreter) is challenging and gives new constraints. Hence you'll need to re-think your application.
If all this is new (and even if you don't choose e.g. Guile as the embedding interpreter): learn and practice a bit of Scheme -e.g. with Guile or PltScheme- (e.g. reading SICP), read a little bit about λ-calculus and closures, then read Queinnec's Lisp In Small Pieces book. Remember the halting problem (which is partly why interpreters are difficult to code).
BTW the syntax you are proposing (e.g. rotate mat 1 by x 90) is not very readable and looks COBOL-like. If possible, have a language which looks familiar to existing ones. Make it easy to read !
Start by reading all the wikipages I am referencing here.
FWIW, I am the main author of MELT, a domain specific language (inspired a lot by Scheme) to extend the GCC compiler. Some of the papers / documentations I wrote might inspire you (and contain valuable references).
Addenda (after question was reformulated)
You seems to invent some formal syntax like
add material 1 to layer 1
rotate layer 1 about x-axis by 90 degrees
translate layer 1 in x-axis by 10 inches
I can't guess what kind of language is it? Are you implementing a 3D printer? If yes, you should stick to some existing standard formal language in that domain.
I believe that such a COBOL-like syntax is really wrong. The point is that it is too verbose, and that you are wishing to implement some domain specific language. I find your example very bad-looking.
Is that syntax your invention, or is there some document specifying (and many thousands already existing lines coded in) your domain specific language. If you are just inventing it, please reconsider the syntax and the semantics.
First, you need to specify on paper the full syntax and semantics of your DSL.
Is your DSL Turing complete? (I guess that yes, because Turing completeness is reached very quickly - e.g. with variables and loops....). If yes, you are inventing a scripting language. Please don't invent scripting language without knowing several programming & scripting languages (then read Programming Language Pragmatics...). The point is that, if your scripting language will become successful, advanced users will soon or later write important programs in it (e.g. many thousand lines). Then, these advanced users will be programmers. In that case, it is very important (for social & economic reasons) to have a DSL well founded and looking familiar (if possible, an extension of some existing scripting language).
If your DSL already exists, stick to its specification on paper. If that specification is not good enough, improve it with formalization (e.g. by writing some BNF syntax, and some formal (e.g. denotational) semantics for it). Publish and discuss that formalization with existing users.
Several industries got some ad-hoc DSLs which became widely used but was ill designed
(e.g., in the French nuclear industry, the Gibiane DSL designed in the 1970s by nuclear physicists, not computer scientists; the US Boeing corporation is also rumored to have made similar mistakes). Then, maintaining and improving the many hundred thousands lines of DSL scripts is becoming a nightmare (and may means losing millions of dollars or euros). So you better stick to some existing scripting language. The advantages are that there exist some culture on it (e.g. you can find dozens of books on Python or Lua, and many trained engineers familiar with them), that the interpreter is widely used and tested, that the community working on them is improving the interpreters, so it has quite few uncorrected bugs.
You should not attempt to design and implement your own DSL if you are not a trained computer scientist. Stick to some existing scripting language (of course their syntax is not like you want it to be), and leverage on existing implementations and experiment.
As a counter-example, J.Ousterhout has invented the widely used Tcl scripting language, with the claim that scripts are always small (e.g. hundreds of line only) and won't grow to big code base; unfortunately, some of them did, and Tcl is known as a bad language to code many dozens of thousands of lines (even if Tcl is an easy and convenient language for tiny scripts). The moral of the story is that if a (turing complete) scripting language is becoming successful, some "crazy" advanced user will code hundred of thousands of script code. So you need that scripting language to be well designed from the start. Hence, you should adopt and adapt a good existing scripting language (and avoid inventing an unfamiliar syntax without having a good knowledge of several existing scripting languages)
later additions
PS: my criticism of Tcl is not entirely subjective: the point is that Tcl was designed for small scripts in mind (read J.Ousterhout's first papers about Tcl), but my point is that when you offer a Turing-complete scripting language, some "crazy" user will eventually write huge scripts for it. Hence, you need to anticipate such "crazy" usage by offering a scripting language which "scales up" to big scripts, so is built according to software engineering practices for large software code base.
NB. Lua is probably a good choice as a language to embed. It is small, has a nice implementation, is well documented, and has good performance. But be careful about memory management issues (and this advice holds for any scripting language).
EDIT: To be more clear, I would like to have a short list of key words
(<15). The order/presence of which would determine which function will
be run.
You can build a small ruleset engine (e.g. something that processes lists of words). You write that engine/function once and just pass the data structures to it.
As an alternative, a solution using regular expressions would be probably the fastest to code (the engine is ready for you), assuming you're familiar with the regexp syntax (if not, it's still a good investment).
You could build a table of keywords and function pointers:
typedef void (*Function_Pointer)(void);
struct table_entry
{
const char * keyword;
Function_Pointer p_function;
};
table_entry function_table[] =
{
{"car", Process_Car},
{"bike", Process_Bike},
};
Search the table for a keyword. If the keyword is found, dereference the function pointer.
The following snippet will execute the function for processing the word "car":
(function_table[0].p_function)();
There is a famous program, called Eliza, which parses sentences for keywords.
Examples can be found at: Eliza C++ examples
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
As I try to increase my knowledge of functional programming, I'm finding it quite difficult to re-imagine the solutions to problems I've solved in an OOP language in terms of functions, particularly where widgets are involved. Sites like Project Euler and 4Clojure are great for learning core functions and techniques for manipulating primitive data, but what I'd really like is a resource that discusses how to idiomatically translate OOP constructs into FP, with particular attention to identifying when and how to use state. (To use a concrete example, what is the best way to implement a piano keyboard in Clojure?)
what I'd really like is a resource that discusses how to idiomatically translate OOP constructs into FP
Don't. That's a classic XY problem.
I hate analogies but an equivalent in engineering might be to say that you've mastered metalwork and want to learn plastics by recreating the same shapes in plastic. In reality, you never want to translate what you know into what you're learning. What you really want to do is learn how to solve familiar problems using new techniques. Going back to engineering, good plastic designs are not the same shape as good metal designs. In terms of programming, solutions build using one paradigm never translate well to another. You should re-solve the problems from scratch.
I know two books that might help:
"Functional Programming for the Object-Oriented Programmer" by Brian Marick.
"Clojure Programming" by Chas Emerick, Brian Carper and Chirstophe Grand. Chapter 12 is about how to "translate" Object-Oriented Design Patterns to Clojure.
I'm not aware of any book that will teach us how to translate OOP constructs into Functional ones. Just give yourself some time and you will grasp the functional idioms.
Don't try to map between OOP code and FP code. The best way to learn a language (spoken language) is to immerse yourself in it and think of it. The same goes for programming languages.
Three years ago I started learning Clojure. At that time, I don't even know what is Lisp and what are functional programming languages. I said: Huh? really what is that? Can I do something useful with Lisp? I read a lot, studied a lot and even better, I got a job in Clojure!
Now programming in functional languages feels natural to me, it makes sense. Programming in data structures and functions are all of what I need. Simplicity!
One thing to keep in mind that functional programming languages aren't difficult by default and OOP languages aren't easy by default.
I've not read this book, but it sounds like quite a good fit for what you're looking for (and I'm very happy with the other Pragmatic Bookshelf books I've read)
Functional Programming Patterns In Scala And Clojure
From the blurb:
By using both the statically typed, type-inferred Scala and the dynamically typed, modern Lisp Clojure, you’ll gain a broad understanding of functional programming.
For each pattern, you’ll first see the traditional object-oriented solution, and then dig into the functional replacements in both Scala and Clojure.
Re: your piano question, you might find core.async and David Nolen's blog posts on UI design with core.async (specifically http://swannodette.github.io/2013/07/31/extracting-processes/) interesting.
In the blog post, he proposes that a user interface (and by extension, a piano), consists of 3 elements - event stream processing, event stream co-ordination and interface representation. And he shows that these are a much more powerful abstraction than the typical OOP Model View Controller. All pretty new though (I don't think core.async is even officially released yet). But if you're looking for the idiomatic Clojure way to model a piano, I think that it may well be along those lines...
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I was wondering how valuable open-source projects are to learn from?
I still consider myself "beginner" due moreso to lack of experience than lack of knowledge- I've read many C/C++ tutorials and taken classes and such, but I just really lack experience. Therefore, even though I understand the major data types and coding techniques, I don't have a solid grasp on what approach to take to use them in my own programming. Therefore, while I continue to read/practice/learn, I have been downloading lots of open-source code (random applications, emulators, games). It is worthwhile looking at them to help learn? I find it extremely interesting, but more often than not just get lost.
Second question, where does one usually start when doing this? Do you hunt down a main() function somewhere? Do you look at headers to see what functions will be available throughout the code and get an idea of what is around to work with?
Please let me know!
R
I personally wouldn't recommend the reading of the source code of open-source projects to a beginner, especially if they're mature projects. It may be overwhelming for a beginner since they tend to be rather large projects with thousands of lines of code, most likely of a non-trivial design.
If you lack experience, then the best way to gain experience is by writing your own programs and taking on your own projects that are of interest to you, in my opinion. You can certainly read other people's code to see "how it's done", but actually trying to implement those ideas yourself in practice does more to help you understand how to write code than just passively reading code. In turn, the gained understanding and experience will allow you to make better sense of other people's code.
It's sort of like math; you may know the formulae, and you can see how mathematicians/teachers/professors/etc. use those formulae, but you won't really understand them until you try them out yourself. Once you do understand them, then the kinds of things mathematicians write will make much more sense.
Try to focus on things you want to do, there's not a lot of point in looking at code for an application that you have no reference point for.
The best place to start would probably be to look at a project like Boost
But formulate a series of application tasks that you'd like to investigate, perhaps graphics, text editing or socket programming... and then work from there.
Getting a good IDE or programmers editor that will help you navigate the code is a major plus.
For example, Emacs + ECTAGS/CEDET/Semantic will help you browse all the functions / classes in a C / C++ project.
I'm agree with #In silico. It's very useful to see other's code, but only when it's a little bit over your level, so that you can learn something. I've seen quite a few projects that were too "over-engineered", so that learning from them when you can't really tell the good from the bad will be a bad idea.
Another thing is to learn from another programmer, when you could ask why he did one way and not another. In this case the difference in levels does not matter.
So I'd suggest programming by yourself, and looking on the other people's code for the same thing after you've tried it. In this way you'll be able to compare the choices you've seen and the decision you've made with someone else (when you don't know a problem in depth, any suggested solution would seem right). You know, In theory, theory and practice are the same. In practice, they are not.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I am learning Clojure and I really am loving some of its features. The time is coming to think of some real "pet projects" and I realize I'm not sure how to actually use Clojure.
I see many web and templating frameworks (e.g. Compojure), but somehow I'm in doubt on whether it's worth it. I feel that in the long run it can't serve the needs of real world applications which you address with Spring, Hibernate and some pieces of the Java EE stack.
On the other hand, I see great potential in the concurrency features but I'm short on ideas on how to really use them.
Enough background, my questions are:
What are the feasible applications of Clojure and functional programming? What idea for a pet project can you suggest which wouldn't be rewriting the stuff I did with OO/Java EE into different syntax? I'm looking for something what really exploits Clojure's potential and leads to a solution which feels a lot better (not just in syntax) than OO/structural programming.
Is it common, or at least reasonable, to mix Clojure and Java? I mean either of using Clojure for tiny libraries in 95% Java projects, or building Java apps on top of the core written in Clojure.
Edit: Thanks for all the great answers. They're all really inspiring. So if you have anything else to add, go ahead and don't be put off by the fact that one has been accepted.
In answer to the "background" part of the question:
I think you should read Jörg W. Mittag's answer to an SO question entitled "Real world Haskell programming". He makes a number of excellent points. Read on for my take on the FP in the real world issue; scroll past the horizontal line for answers to the two actual questions.
There's a number of FP-centric companies which seem to be really good at what they're doing; for some examples, google Jane Street (OCaml), Galois (Haskell), FlightCaster (Clojure for backend heavy lifting; I seem to remember reading that their frontend is currently done in Rails). Supposedly automated trading strategies are often coded in FP-oriented languages; that would indeed make perfect sense, although I have no inside data to confirm this. For additional examples to do with Clojure, see the list of companies on the success stories page.
Some people seem to be enjoying a degree of success in addressing the needs of real world applications in Rails, Django etc. It would appear that they feel no need to touch J2EE & friends. Not that these have much to do with FP, but they are like FP in that they're nothing like the "Enterprise Languages" of the present.
As for the two actual questions:
Why not just pick up whatever it is you've last been thinking to do and do it in Clojure? Obviously anything can be done in Java (and most things probably have been), but a leaner language might make the product cleaner, the experience more pleasant and less time consuming etc.
About mixing Clojure and Java -- I've seen a decent amount of Clojure code using a couple of classes coded directly in Java (for whatever reason). I've tried going the other way around myself and it's a bit of a pain in that it's much simpler to work with interface inheritance than class inheritance in Clojure, unexpected coupling in the Java code can seriously interfere with the ability of the Clojure code to do things in the most natural way etc. Still, it's entirely possible to extend a Java programme in Clojure and it seems like a particularly safe & sane way of experimenting with it for the worried Java developer.
Functional programming can be applied to almost any task. Web applications, scientific applications, games, you name it.
It is very common to mix Clojure and Java, since Clojure does not have many dedicated libraries for things like I/O or networking.
Organizations that already have a lot of Java code can use Clojure for small subsections of their Java projects.
For new projects, it is usually more effective to use Clojure as the high-level driver language, calling Java libraries where necessary.
I have been working on a small web application using Clojure, and while there is nothing special about the application that could not have been done in a different language, the experience of writing it has been completely different. I have written web apps using ASP.net and moving to Clojure was less about learning the different syntax and more about learning a different way to think and program. Having to learn a different way to think will occur regardless of the project you choose to work on, so I would worry less about finding the perfect functional project and more about finding something you just want to work on.
I think the answer to this has a great deal to do with the context your project is embedded in, and the constraints that imposes on you. Absent social factors I think Clojure is likely at least as "good" a language as Java is for any problem, with the possible exception of cases where you need the last bit of performance. And even in those cases things are not nearly as simple as they seem. For one thing some future version of Clojure can probably, in the theoretical limit, be compiled to bytecode that is as "fast" as what Java is compiled into (assuming a bit more work from the programmer at bottlenecks.) More importantly, optimization is a multi-factorial problem, and one in which programmer productivity and the flexibility of code factors heavily. So while there is a sense in which it would be accurate to say that Clojure is slower than Java, that sense might not be the important one when discussing the performance of a particular application.
So I'd say that if you disregard social factors Clojure's use cases are close to a superset of Java's. I wouldn't try to write a Linux kernel module in clojure though...
Of course, it's true that not all problems have equally natural solutions in functional languages. But people have come up with some interesting ways of dealing with some of the cases where FP seems to map badly to the domain, and anyway Clojure actually offers you enough escape hatches from pure FP that if you really feel the need to write part of your program in an imperative style you can (though of course you give up some of the benefits of Clojure in that case.) In the worst case you could use Clojure to drive the Java library in much the same way that you would in Java... it's hard to imagine a case where that would be a good idea, but in most cases that would not be markedly inferior to just using Java, and in many it might be better.
I'm still a neophyte at Clojure, though I've been programming in CL and scheme for a long time, and I spent about five years writing Java for a living. But I would probably prefer Clojure to Java for just about anything even without knowing it quite as well, as long as there were no social factors involved.
It would be a mistake to dismiss social factors though. I've been a Lisp programmer long enough to have a finely honed instinct for how well a Lisp will work in a given context. I've introduced Lisp to commercial settings where it has been a big win, and I've introduced it to settings where it really wasn't. I'd think long and hard about staking your career on successfully transitioning a team of programmers to any Lisp, Clojure included, particularly if they are not too keen on the idea.
Just to give you an idea of what I think Clojure might be useful for, I am currently writing a lot of poker-related code in Clojure. Some of it is pretty simple stuff (finding the best five card hand you can make from seven cards) and some of it is a bit more interesting (looking at someone's playing history and extracting meaningful trends from it using a few heuristics and some basic statistics.) None of it requires much in the way of Clojure's sophisticated concurrency mechanisms, but it is still much nicer (for me at least) in Clojure than it would be in, say, Java.
There are certainly some other cases that someone might describe where Clojure wins big because of its sophisticated mechanisms for managing concurrency, etc. I am aiming at something more modest- I am just pointing out that even if you don't need those mechanisms you might find Clojure a very congenial language for general purpose programming, albeit one that requires you to rethink how you abstract things if you're coming from an imperative/OO background. And hey, if you need the concurrency mechanisms (as you might, the way things are going), at least you already know Clojure.
I like writing game programs when I learn a new language.
I am in the process of learning Clojure and started writing a Spider solitaire player. If you have never played Spider, don't start; it is very additive :-). See http://www.spidersolitaire.org/.
In writing this game, I am getting to use several things that I want to learn: functional programming, concurrency, Java-interop (for Swing), etc.
I have also started writing a Bejeweled player (http://www.popcap.com/games/free/bejeweled2), but have run into a problem finding the definitive rules for scoring the game.
I am a new to professional development. I mean I have only 5 months of professional development experience. Before that I have studied it by myself or at university. So I was looking over questions and found here a question about code quality. And I got a question related to it myself. How do I increase my code understanding/reading skills? Also will it improve the code quality I will write? Is there better code notation than Hungarian one? And is there any really good books for C++ design patterns(or the language doesn't matter?)?
Thank you in advance answering these questions and helping me improving :)
P.S. - Also I have forgot to tell you that I am developing with C++ and C# languages.
There is only way I've found to get better at reading other peoples code and that is read other peoples code, when you find a method or language construct you don't understand look it up and play with it until you understand what is going on.
Hungarian notation is terrible, very few people use it today, it's more of an in-joke among programmers.
In fact the name hungarian notation is a joke itself as:
"The term Hungarian notation is
memorable for many people because the
strings of unpronounceable consonants
vaguely resemble the consonant-rich
orthography of some Eastern European
languages."
From How To Write Unmaintainable Code
"Hungarian Notation is the tactical
nuclear weapon of source code
obfuscation techniques; use it! Due to
the sheer volume of source code
contaminated by this idiom nothing can
kill a maintenance engineer faster
than a well planned Hungarian Notation
attack."
And the ever popular linus has a few words to say on the matter.
"Encoding the type of a function into
the name (so-called Hungarian
notation) is brain damaged—the
compiler knows the types anyway and
can check those, and it only confuses
the programmer."
- Linus Torvalds
EDIT:
Taken from a comment by Tobias Langner.
"For the differences between Apss Hungarian and Systems Hungarian see Joel on Software".
Joel on Software has tips on how to read other people code called Reading Code is Like Reading the Talmud.
How do I increase my code
understanding/reading skills?
Read read read. Learn from your mistakes. Review answers on SO and elsewhere. When you can think back on a piece of code you wrote and go "aha! I should've done xyz instead!" then you're learning. Read a good book for your language of choice, get beyond the basics and understand more advanced concepts.
Then, apart from reading: write write write! Coding is like math: you won't fully grock it without actually solving problems. Glancing at a math problem's solution is different than getting out a blank piece of paper and solving it yourself.
If you can, do some pair programming too to see how others code and bounce ideas around.
Also will it improve the code quality
I will write?
See above. As you progress you should get more efficient. It won't happen by reading a book on design patterns. It will happen by solving real world problems and understanding why what you read works.
Is there better code notation than
Hungarian one?
It depends. Generally I avoid them and use descriptive names. The one exception where I might use Hungarian type of notations is for UI elements such as Windows Forms or ASP.NET controls, for example: using btn as a prefix for a Submit button (btnSubmit), txt for a TextBox (txtFirstName), and so on but it differs from project to project depending on approach and patterns utilized.
With regards to UI elements, some people like to keep things alphabetical and may append the control type at the end, so the previous examples become submitButton and firstNameTextBox, respectively. In Windows Forms many people name forms as frmMain, which is Hungarian, while others prefer naming it based on the application name or form purpose, such as MainForm, ReportForm, etc.
EDIT: be sure to check out the difference between Apps Hungarian and Systems Hungarian as mentioned by #Tobias Langner in a comment to an earlier response.
Pascal Case is generally used for method names, classes, and properties, where the first letter of each word is capitalized. For local variables Camel Case is typically used, where the first letter of the first word is lowercase and subsequent words have their first letters capitalized.
You can check out the naming conventions and more from the .NET Framework Design Guidelines. There is a book and some of it is on MSDN.
And is there any really good books for
C++ design patterns(or the language
doesn't matter?)?
Design patterns should be applicable to any language. Once you understand the concept and the reasoning behind that pattern's usefulness you should be able to apply it in your language of choice. Of course, don't approach everything with a "written in stone" attitude; the pattern is the goal, the implementation might differ slightly between languages depending on language features available to you. Take the Decorator pattern for example, and see how C# extension methods allow it to be implemented differently than without it.
Design Pattern books:
Head First Design Patterns - good beginner intro using Java but code is available for C++ and C# as a download (see "book code and downloads" section on the book's site)
Design Patterns: Elements of Reusable Object-Oriented Software - classic gang of four (GOF)
Patterns of Enterprise Application Architecture - Martin Fowler
If you're looking for best practices for quality coding in C++ and C# then look for the "Effective C++" and "More Effective C++" books (by Scott Meyers) and "Effective C#" and "More Effective C#" books (by Bill Wagner). They won't hold your hand along the way though, so you should have an understanding of the language in general. There are other books in the "Effective" series so make sure you see what's available for your languages.
I'm sure you can do a search here for other recommended reading so I'll stop here.
EDIT: added more details under the Hungarian Notation question.
I can't speak for everyone else, but in my experience I've found that the best thing I learned about making readable and/or in general better code was reading (and ultimately cleaning) a lot of other people's code. Some people may disagree with me but I think it's invaluable. Here's my reasoning:
When you start programming, its difficult to determine what is crap vs. not crap vs. good. Being logical, rational and extremely intelligent help in making good code, but even those factors don't always contribute. By reading others works and doing the dirty work, you'll have gone through the experience of what works and what doesn't. Eventually, you'll be able to mentally navigate those minefields that others had to cross and you'll be prepared to avoid those identical minefields.
By reading other's works, you gain insight into their mind and how they tackle a problem. Just from an architecture or technique aspect, this can be very useful to you whether their
tactics were good or bad. By reading other peoples successful or unsuccessful implementation, you've gained that knowledge without putting in the actual time it took them to learn it.
Design patterns are extremely useful. Only time and experience with them will help you in knowing what the appropriate pattern for whichever problem. Again, read other peoples' code for this if they've successfully built some pattern that may be useful for you.
When dealing with extreme problems where people's work falls short, you learn to research and dive into the internals of whatever system/language/platform/framework you're working with. This research ability on your own is very useful when all else fails. But you'll never know when to start looking or for what until you get through the crud of other people's work. Good code or bad, it's all valuable in some form or fashion.
All these notations and formats and nomenclature are helpful, but can be learned or implemented rather quickly and their payoff is fairly substantial. By reading code from other people, you'll develop your own style of logic. As you encounter other peoples work and the tremendous amount of effort it takes to read through, you'll learn what logical pitfalls to avoid and what to implement the next time for yourself or even how to fix bad code even faster.
I've never felt as if I was a great programmer. Not to say I'm a bad one either, but I feel confident in my abilities as my experience has taught me so much and my ability to adapt to every situation is what makes me a solid programmer. Learning from other people and their code has helped me. Whether their work was good or bad, there's always something you can take from them and their experience, add it to your memories, knowledge, etc.etc.
Ask other people to read your code! Try and see if you get a fellow coworker or similar to have a code review with you. Having someone else comb through your code and ask you questions about your code will provide new insights and critiques to your style and techniques. Learn from your mistakes and others.
Just to give you a bit of encouragement, I've been a professional programmer for 30 years now, and I still find reading other people's code very difficult. The major reason for this, unfortunately, is that the quality of the code follows Sturgeons Law - 90% of it is crap. So don't think it's your fault if you find it hard going!
The biggest improvement in readability of my code came about when I started liberally using white space.
I found this article on Joel on Software to be very relevant to the Hungarian notation debate.
It seems that the original intent of the notation was to encode type information that wasn't immediately obvious- not whether a variable is an int (iFoo), but what kind of int it is- such as a distance in centimeters (cmFoo). That way, if you see "cmFoo = mBar" you can tell that it's wrong because even though both are ints, one is meters and the other is centimeters, and thus the logic of the statement is incorrect, even though the syntax is fine. (Of course, I personally prefer to use classes such that that statement wouldn't even compile, or would do the conversion for you).
The problem was at some point people started using it without understanding it, and the world was cursed with lots of dwFoos and bBars.
Everyone needs to read that article- Making Wrong Code Look Wrong
How do I increase my code
understanding/reading skills?
Reading code is like dancing by yourself. You need a partner, and I suggest a debugger.
Stepping through code with a debugger is a true, lively dance. I recommend getting a quality, open-source project in the language of your choice, and then step through with the debugger. Concepts will come alive if you ask "why did that happen?", "what should happen next?".
One should ultimately be able to reason about code without a debugger; don't let it become a crutch. But that said, it is a very valuable tool.
Reading code is a lot like reading literature in that you need to have some insight into the author sometimes to understand what you're looking at and what to expect. They only way to improve your comprehension skills is by reading as much code and possible and trying to follow along.
I think a lot of what is mentioned here is applicable to coding...
Reading and understanding skills are a question of time. You will improve them as you get more experienced. Also depends in the quality of the code you are reading.
Keep in mind that sometimes it's not the best idea to learn directly from what you see at work. Books will teach you the best practices and you will be able to adapt them to yourself with the experience.
I am reading the Head First Design Patterns at present and it is very useful. It presents the information in a novel way that is easy to understand. Nice to see they have a C# version for download.
There will always be struggles with reading code unless you are Jon Skeet. This isn't to say that it is a big problem, rather that unless you can eat, sleep, breathe in that programming language, it will always take a little time to digest code. Looking at other people's code is certainly a good suggestion for helping in some ways but remember that there are many different coding conventions out there and some may be more enforced than others, e.g. interface names start with an I to give a simple example. So, I guess I'm saying that even with Visual Studio and Resharper, there is still a little work to understand a few lines of code since I can't quite write out sentences in C# yet.
1) Educate yourself. Read relevant literature.
2) Write code
3) Read code
4) Read relevant blogs.
Visit http://hanselminutes.com . He is a programmer from microsoft. Even though you don't program on microsoft stack, it's good to read through. There is a podcast in there that answers this question.
Another suggestion is to make sure you have the appropriate tools for the job before you start digging into a piece of code. Trying to understand a code-base without the ability to search across the entire set of files is extremely difficult.
Granted, we very rarely have the entire set of files, especially in large projects, but whatever boundaries you draw, you should have good visibility and searchability across those files. Whatever lies outside those boundaries can be considered 'black box' and perhaps lies outside the scope of your grokking.
There are many good open source editors including Eclipse and the CDT. Spending some time learning how to effectively create projects, search across projects, and enable any IDE-specific tooltips/helpers can make a world of difference.