Related
I'm writing to ask for some guidance on choosing a language and course of action in learning programming. I apologize if this type of question is inappropriate for Cross Validated, please advise me to another forum if that is the case.
I've seen thread after thread with questions from newbies, asking, "What is the best language to start with?" and then it always starts a flame war or someone just answers, "There's no best language, it's best to pick one and start learning it." My question is a little bit more focused than that.
First off, I've been programming my whole life, in very limited capacities. My deepest training was in C++. Whilst in my EECS degree program, I resolved to never be a software developer because I couldn't stand not interacting with people for such long periods of time. Instead I realized I wanted to be a math teacher, and so that is the path I have taken.
But now that I'm well down that path, I've started to realize that perhaps I could develop my own software to help me in the classroom. If I want to demonstrate the Euclidean algorithm, what better way than to have a piece of software that breaks down the process? Students could run that software as part of their studies, and the advanced students might even develop programs for themselves. Or, with an Ipad in hand, why not have an app that lets students take their own attendance? It would certainly streamline some of the needs of classroom management.
There's obviously a lot of great stuff already out there for math, and for education, but I want a way to more directly create things specific to my lectures. If I'm teaching a specific way of calculating a percent, I want to create an app that aligns with my teaching style, not just another calculator app that requires the student to learn twice.
The most I use in class right now is iWork Numbers/Microsoft Excel for my stats class. Students can learn the basic statistical functions, and turn some of their data into graphs.
I have dabbled a bit with R, and used Maple in college. I've started the basic tutorials for OS X/iOS development and have actually made good progress making an OS X app that takes a text string, converts it to numbers, and performs encryption using modular addition and multiplication. I sometimes use Wolfram|Alpha to save myself some time in getting quick solutions to equations or base conversions. I know of MatLab, Mathematica, and recently people have been telling me to check into Python or Ruby. I also know basic HTML, and while it's forgotten now, learned Javascript and PERL in college.
If I keep on the path of Obj-C/Cocoa, I think it will have great benefits. Unfortunately, anything I produced for Mac would only be usable on a Mac, so it wouldn't be universal for all of my students. Perhaps then learning a web language would be better. Second, I'm wondering if the primary use is mathematical, then perhaps my time would be better spent learning Mathematica Programming Language, or R, or something based less on GUI and more on simple coding of algorithms, maybe Python or Ruby?
It seems that Mathematica already has a lot of demos for different math concepts, so why reinvent the wheel is also a question I have. I think overall, it would be good to have more control and design things the way I need. And then, if I do want to make an "Attendance" app or something else, I would already have the programming experience to more easily design something for my iPad or MacBook.
The related question to this is what is a good language to teach to my students? In his TED talk, Conrad Wolfram says one of the best ways to check the understanding of a student is have them write a program. But if Mathematica does the math virtually automatically for them, then I'm not sure that will get the deeper experience of working out logic for themselves, like you do when you're writing C, or a traditional procedural language.
I know that programming takes time to learn, but I also know that at this point, my goal is not to be able to make an app like "Tiny Wings." With the app store ease, some of my work may be an extra revenue stream, but I see myself as more of a hobbyist, and now teacher looking to software development specifically for its ability to help me demonstrate mathematical concepts.
I think I will push ahead with Obj-C/Cocoa for OSX/iOS, but if anyone has some better guidance regarding all of the other available stuff, it would be much appreciated. I don't think I would want to go fully to the web (I like apps), but perhaps someone could suggest a nice way of bridging what I produce in XCode to a universal web version. For example, if you come up with an algorithm in obj-c is it easiest to transition that to ruby and run it online, or is there another approach that works better?
Mathematica is pretty awesome for the first part of your question. I've used the interactive mode (Manipulate[]) for explaining things to my colleges (and myself). It makes really nice dynamic figures and is fairly expressive (although your code can end up looking like line noise). It is very powerful, but it does far less for you than you might think. It's pretty intuitive, which is a good thing for teaching.
You could use Scala if you want an "easy" way to make a domain specific language for teaching. Python seems to confuse people as a first programming language. Objective C seems like a completely random choice to me.
Mathematica then. It's worth the price. But anything that is interpreted and has an interactive shell is probably better than a compiled language. BBC BASIC?
Nothing beats Haskell for general-purpose mathematical programming. The wiki's quite extensive and the IRC channel (#haskell on Freenode) is great for asking questions. If you statically link your binaries on compilation, you should be able to run your programs on just about any system (with a few exceptions, e.g., libgmp).
Haskell code reads (roughly) like mathematical notation once you get the hang of it, so it can really help to tie things together for your students who are motivated to write their own programs. The purely functional style can be beneficial, as well, since it focuses less on I/O and the marshalling of data (perfectly useful in applications, perhaps less so in pure math), and more on the actual creation and refinement of functions and algorithms. You can even compose functions just as you would on paper.
If you want to get really serious, you could also look into Coq or Agda, but those might be a bit much for most classes.
For a Haskell program idea for an educator, check out this link.
A nice list of arguments can also be found at:
Eleven Reasons to use Haskell as a Mathematician and the book The Haskell Road to Logic, Maths and Programming
Are there any Principles for Clojure ?
a. Like the S.O.L.I.D. Object-Oriented Design Principles for OO languages like Java ?
b. or others more heuristic, like "Tell don't ask", "Favor Composition vs Inheritance", "Talk to Interfaces" ?
Are there any design patterns (for flexible code) ?
What is the counter part of the basic of functional-programming like encapsulation for object-oriented ?
Know of any resources for these ?
To your first question: no. †
Clojure is here to help you get things done correctly, quickly, and enjoyably. Everything after that is gravy.
And there's a lot of gravy. I don't presume to know the Clojure way, even if there is one, but here are some guidelines I've been told and have discovered while writing in Clojure:
First, get something working. Then you can examine, test, and optimize if necessary. There's a reason that the time macro is in the core language. Correctness before quickness, to be cute.
Abstract. If you are repeating yourself, you're probably not doing it right. Compose, curry and combine functions.
Separate side-effects from your logic. e.g. if you want to format and save a string, format it in one function, then use another function to save it, however you need to.
3a. Don't go too crazy with this. Sometimes it's better to have a a few anonymous functions than a bunch of one-line defns littering your code.
Test. Rich gave you a REPL for a reason; use the hell out of that REPL.
Don't clutter your namespace. We're clean in Clojure-land. Qualify your uses or use :only what you need. Make your code readable.
Know the core library. Not just clojure.core, but clojure.java.io, clojure.string, clojure.set and everything in between. If you think Clojure should have a function to do X, it probably does. You can use apropos (from, yes, another core library: clojure.repl).
Document your code. Docstrings are a beautiful thing. If you have a tendency to be verbose, the doctsring is the place to let loose. But, know too that good code often "documents itself". If the code is self-explanatory, there's no need to be pedantic.
This is a functional language. When you can, use a function. Protocols, macros and records are all great: but when you can get away with it, use a function. You can compose, combine, map, reduce, iterate (the list goes on, and on, and on…) functions. That's really nice.
Above all, break the above rules if it makes sense. But be prepared to rethink and refactor. If you've kept your code modular enough, refactoring your code should be a matter of reorganization and recombination.
Some other tips: read other people's code. If you begin to read code, and become good at reading code, you'll become better at writing your own, and you're likely to learn new things, too: there's more than one way to do just about everything.
Finally, read though the Clojure Library Coding Standards to get an idea of what's expected in production Clojure code.
† At least, not yet.
Hard question.
Clojure is very flexible.
So they are best practices, but they aren't nearly as important as for java.
I write here a few examples of advices from the most general to the most particular families.
There are advices for programming in general:
write a lot of tests, write something correct and nice, profile and optimize when needed
There are advices for functional programming:
write small functions, write pure functions, compose the small functions, factor your code through functions, try to use combinators when possible...
There are advices for LISP:
use macro to factor out repetitive patterns, build your program bottom-up. (See Paul Graham's 'on LISP' for a better explanation than mine)
There are also some advices specifically for Clojure:
follow the careful analysis of state and identity ( http://clojure.org/state , for a very good explanation), try to use seqs and their functions when possible, write doc strings for functions
A good source for more advices are the Clojure Library Coding Standard
http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
But all these advices are just advices, and Clojure can be used by someone that do not want to follow these advices, because, as a Lisp, it is very flexible.
As far as design pattern are concerned, functional programmer rarely think in these terms, as most of them has been designed for OO languages and do not apply in a functional language.
Peter Norvig has interesting slides on Design Pattern and LISP/Dylan:
http://norvig.com/design-patterns/
Hope that helps.
1a) I don't know of something like that but every book about FP will do something like that.
1b)
"Favor Composition vs Inheritance" --> is already taken care of because you started with FP
"talk to abstractions" --> more general
"be lazy when you can"
"avoid state"
"Use PURE FUNCTIONS!!!"
List item
....
2.) You can use some of the some same design patterns they are just much easier to implement. Some of them make less sense but normally. FP folks don't make a big deal out of it.
(This is about GoF patterns I only know them)
Look at the observer-pattern for example. In Clojure you can use add-watcher function witch make the observer-pattern obsolete.
3.)You can use encapsulation in name spaces look at defn- or you can hide your function in other functions. In the Joy of Clojure are some examples. You can push it as far as you want.
The Don't Repeat Yourself (DRY) principal applies very well to clojure. The language is very flexible and really promotes composing abstractions in ways that can really reduce the amount of boiler place code very close to zero.
some examples of ways to remove duplicated code are:
only use lazy-cons when generating original data where no variant of map will do. If you find your self writing (lazy-seq (cons (do-something data) (call-myself (rest data))), check to see if map or iterate will do what you want.
use small functions and compose them liberally. if a function needs to format some data, wrap it in XML, and send it over a network. write these in three small functions and then use the (def send-formated-xml (comp send xml format)) this way you can map the format function onto some data later etc.
when the language absolutely can not express you repeated pattern, use a macro. Its better* to use a macro than to repeat your self. and always remember the first rule of macro club is do not use a macro.
This video presents the SOLID principles, and how to apply them in Clojure.
It shows how these principles hold in the Functional world as much as in OOP, because we still need to solve the same underlying problems. Overall, it made me think Functional Programming is better suited for SOLID design.
there is a post in a blog mentioning "thinking in clojure" here and it gives some pointers to the book The Joy Of Clojure, and to some other books (and even links to some videos)
now, i got the book The Joy Of Clojure, read a bit of it, and it promises to teach me "The Way Of Clojure". hope it turns out telling me what i'm looking for, some principles...
this book is work it progress but you can buy an "early access edition" from manning here and get 40% of with code "s140". see info here
I'm a big fan of functional programming in general, Schemes in particular, and PLT-Racket ideally. I am wondering what concrete steps are likely to get me into a position where coding Scheme (or some functional language) is the bulk of the work.
I'm actually quite interested in academia, but on the other hand, I don't feel like I necessarily have what it takes (at least not at the moment) to do a top-tier Ph.D in CS. I definitely would prefer to have some real-world experience putting complex systems together in Scheme either way. Does anyone have any advice for an aspiring Schemer?
Start writing some Scheme libraries, then blog about the libraries you've wrote, get noticed in the community.
This will always give you leverage when applying for a position, employers like to have some evidence of what you can do.
dalton has the right idea; you want to build something you can show off. To find out about needs, you could go to http://srfi.schemers.org/, which is an archive of proposals for Scheme libraries and other improvements to Scheme, and see what you think you can contribute to. Or make contact with the Racket team; you may be able to contribute to Racket directly.
If you want to leverage something popular and in the news: App Inventor is based on Google Blocks, which are in turn based on Kawa, which is a Scheme dialect [*].
If you can show off your skills by putting together blocks and making them available for the community...it's a natural way to take advantage both of your multi-language skills and something currently getting press coverage.
Regards,
Dak
[*] and I forgot to say that earlier, mea culpa!
Not going to accept my own answer because it is, in general, worse than the one #dalton gave, but!
I got a grant through Turbulence.org to write an art and thus was paid to scheme! Or racket, if you want to be a pedant. repo here...
F# is getting popular in the finance sector:
http://cs.hubfs.net/forums/thread/16004.aspx
My professor told us that we could choose a programming language for our next programming assignment. I've been meaning to try out a functional language, so I figured I'd try out clojure. The problem is that I understand the syntax and understand the basic concepts, but I'm having problems getting everything to "click" in my head. Does anyone have any advice? Or am I maybe picking the wrong language to start functional programming with?
It's a little like riding a bike, it just takes practice. Try solving some problems with it, maybe ProjectEuler and eventually it'll click.
Someone mentioned the book "The Little Schemer" and this is a pretty good read. Although it targets Scheme the actual problems will be worth working through.
Good luck!
Well, for me, I encountered the same problem as you do in the beginning when I started doing OCAML, but the trick is that you must start thinking about what you want from the code and not how to do it!!!
For example, to calculate the square of list's elements, forget about the length of the list and such tricks, just think mathematically like that:
if the list is empty -> I am done
if not, then the list must have a head and tail -> you calculate the square of the head, then ask your function to do the same with the tail.
Just think about the general case and the base one, and that you are emitting data and not modifying it (unless you want to modify it ;) ).
Good luck!
You could check out The Little Schemer.
How about this: http://www.defmacro.org/ramblings/lisp.html
It is a very simple, step-by-step introduction to thinking in lisp from the point of view of a regular imperative programmer (Java, C#, etc.).
For educational purposes I would recommend PLT Scheme. It is a portable and powerful environment with very good examples and an even better documentation. It will help you to discover the thoughts behind functional programming step by step and in a very clean way. Choosing a little application to implement will help you learning the new language.
http://www.plt-scheme.org/
Additionally "Structure and Interpretation of Computer Programs" of H. Abelssn, G. Sussman, and J. Sussman is a very good book regarding Scheme (and programming).
Regards
mue
Take a look at 99 Lispy problems
Some thoughts on Lisps, not specific to Clojure (I'm not a Lisp expert, so I hope they're mostly correct and useful):
Coding in AST
I know little about compiler or interpreter theory, but every time I code in Lisp, it amazes me that it feels like directly building an AST.
That's part of what "code = data" means, coding in Lisp is a lot like filling data structures (nested lists) with AST nodes. Amazing, and it's easy to read too (with the right text editor).
A Programmable Programming Language
So code chunks are just nested lists, and list operations are part of the language. So you can very easily write Lisp code that generates Lisp code (see Lisp macros). This makes Lisp a programmable (in itself!) programming language.
This makes building a DSL or an interpreter in Lisp is very easy (see also meta-circular evaluation).
Never reboot anything
And in most Lisp systems, code (including documentation) can be introspected and hot swapped at run time.
Advanced OOP
Then, most Lisp Systems have some sort of Object System derived from CLOS, which is an advanced (compared to many OOP implementations) and configurable Object System (see The Art of the Metaobject Protocol).
All these features where invented long ago, but I'm not sure they are available in many other programming languages (although most are catching up, e.g. with closures), so you have to "rediscover" and get used to these by practicing (see the books in other answers).
Just remember: it's all data!
Write some simple classic functions that Lisp is good at, like
reverse a list
tell if an atom is somewhere in an s-expression
write EQUAL to tell if 2 s-expressions are equal
write FRINGE to get the list of atoms at the fringe of an s-expression
write SUBST, then write SUBLIS
Symbolic differentiation
Algebraic simplification
write a simple EVAL and/or APPLY
Understand that Lisp is good for these kinds of no-side-effect functional programs.
It is also useful for stateful side-effect (non-functional) programs, but those are more like "programs" than "functions".
Which is better for a given application depends on the application. In general, it should contain no less, and no more, state information than necessary.
Easy!
M-x lisp-mode
OK, OK, so you might not have Emacs for a brain. In all seriousness, what you need to do is to get really good at recursion. This can be quite a brain warp initially when trying to extend the concept of recursion beyond the canonical examples, but ultimately it will result in more fluid, lispy code.
Also, a lot of people get hung up on the parenthesis, and I don't really know why - the syntax is very simple and consistent and can be mastered in minutes. For me, I came to Scheme after having learned C++ and Java, and I always thought that the difference between "functions" and "operators" was a false dichotomy, and it was refreshing to see that distinction eliminated.
As far as functional programming goes, as long as you can wrap your head around the fact that a function is a first-class value and can be passed both into and out of other functions you should be fine. The usefulness of this will become clear over time, but it's enough that you can write function-taking and function-returning functions.
Finally, I'm not sure what support Clojure has for macros, but they're considered an essential part of lisp. However, I wouldn't worry about learning them until you're deeply familiar with the above items - though macros are incredibly useful and versatile, they're also used less often than the other techniques I mentioned.
I'd start with a language that can be interpreted. I found Moscow ML to be fairly easy. It is a lightweight implementation of Standard ML.
My personal practice is to find a small project (something that might take 3-5 nights hacking away) and implement it. How about a blog filter tool? Maybe just a Towers of Hanoi or Linked List implementation (those are usually 1-night projects).
The way it usually works out is I implement it poorly the first time, throw away what I had, and it finally clicks a few hours in.
A HUGE help is taking a course in something like... um... LISP! :) The homework will force you to confront a lot of the concepts and it clicked for me long before the semester ended.
Good luck!!
Good luck. It took me until about halfway through the "Programming Languages" course in college before Scheme "clicked". Once that happened, though, everything just made sense, and I fell in love with functional programming.
Write a Lisp interpreter in Lisp.
If you haven't alrady, read up on what makes lisp a unique language. If you don't do this first, you'll be trying to do the same things you could do in some other programming languages.
Then try to implement some small thing (try to make it useful to you or you might not have the motivation).
Lisp in a box is a great way to get your feet wet.
For me the important thing is to make sure you do everything in a 'lisp-y' way. Don't be tempted to think 'In Java I'd use a for loop here, how do I do for loops in Lisp?' but to go through enough examples and tutorials (as someone pointed out, SICP is perfect for this) that you can start to spot when code looks 'Lisp-y' and recognise common language paradigms.
I certainly know the feeling of looking at some code I've just written and intuitively knowing that it's correctly idiomatic for that language and platform/framework - that, I think, is when it 'clicks'.
Edit: And kudos for choosing a functional language, lesser students would have just done it in Java :)
Who said it is going to click? I'm always confused
But if you think about how much abstraction it is possible to hide away, behind lisp macros. Then your brain will explode.
:)
I'd check out Programming Clojure. It's a great book for non-lispers.
In addition to what other SO'ers have already suggested, here are my 2 cents:
Start learning the language and try out a few simple numerical/hobby problems in the language
IMPORTANT: Post the solution/code to StackOverflow, asking for people's opinion if that is really the LISPy way to do it.
Best of luck!
I work in a Microsoft environment, so I can use my C# hammer on any nails I come across. That being said, what languages (compiled, interpreted, scripting, functional, any types!) complement knowing C#, and for what purposes? For example, I've moved a lot of script functionality away from compiled console apps and into Powershell scripts. If you're an MS developer, have you found a niche in your world for other languages like F#, IronRuby, IronPython, or something similar, and what niche do they fill?
Note: this question is directed at the Microsoft dev people since I can't run off and start installing LAMP stacks around my company, and therefore having to support it forever. :) However, feel free to mention any other languages that you found interesting to fulfill a certain task/role in your world apart from your main language.
Python/Perl/Ruby/PowerShell are great supplements to C#/VB.NET. If your boss hands you a text file and says insert it into the database once or twice, then any of Perl/Python/Ruby (I'm not sure about powershell but I imagine it is not that much more difficult) should be fine to parse it. Either way, for your main applications you will probably be stuck in C#. You can use one of the more dynamic languages to do code generation in C#.
Since you are in a Microsoft Environment, probably your best chance at getting your solution accepted is PowerShell. Next to that I'd say IronPython or something else that integrates with the CLR. But main issue is that for someone else to maintain what you do, they would have to know whatever language you are using. MS in the future has plans to use PowerShell a lot more, so it is probably easier to justify PowerShell then say Python/Perl/Ruby.
If you are just processing a text file for one time use. Or creating a one time code generator to generate all the code and then intend to maintain the generated code, then it doesn't matter. You are the one who will consume the results and if you save time using Perl then more power to you. But if you are doing something that will be used over and over again (like an active code generator where you change the templates and run the generator instead of maintaining the generated code) then other developers working on what you did will need to know the language you used. It is much harder to argue learning Perl/Ruby/Python in a Microsoft Shop. But PowerShell seems like the easier argument. I think the MS grand plan is that eventually applications will expose more functionality for power shell through commandlets. Assuming this happens then PowerShell is even more of a no-brainer because it will expose tons of scriptable functionality that you won't get any other way.
A nice scripting language is always a good tool to have on you belt. See Ruby, or Python.
I use python for prototyping, since there's almost no turn around time between edits and actually running the new version of the code. I may even end up using it for a real project - the more I use it, the more I like it.
It will take some getting used to as a C# programmer, though - the indentation-defines-structure system it uses is a little weird at first.
Since you are in a MS shop, I would suggest PowerShell as a decent scripting language to learn. It plays well with C#.
I'm a big fan of Ruby too.
I'd like to second or third python. Specifically, IronPython (ttp://www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython) lets you learn python but also gives you access to the .net framework goodies.
It's quite nice for scripting-related tasks so it'll probably be useful for your day-to-day coding life, and also a nice way to muck around in an experimental coding/prototyping way.
While it's a bit of a fringe language, I'm compelled to mention Erlang. Erlang is an excellent language to have in your toolbox since it's unusual strengths tend to compliment other programming platforms. Erlang is very useful for building distributed, concurrent, fault-tolerant systems. It's used a lot in the instant-messaging and telephony world where there's a need for distributed, yet interconnected architectures.
Maybe play around with Boo and see what you think.
Boo at Codehaus.org
Boo at Wikipedia
If your using the .Net framework the language is really not important as the compiler and interpreter create the same IL code in any case.
If you step away from the .Net world, I am of the opinion that development tools and languages are a tool box. I strive to use the right tools for the job at hand, taking into consideration what the skill base of the other developers are and what direction a company is seeking of course (I'm a consultant).
I'm with jjnguy. Try one of the scripting languages. Plus as a bonus, when you learn Ruby/PythonPearl, etc...it's a gateway drug...err language to developing for other environments.
Trying out languages outside of your normal toolbox will give you new ways of approaching things in your current favorite language. Even if you don't use them for serious projects languages like Perl (for data mangling), Lisp (functional programming), and Javascript (prototype based programming) will teach you new ways to think about problems in your current language.
As a web developer by trade, you might look into the XSLT/XPath family as for certain types of XML processing they can be very powerful tools.
Granted, in C# 3.x Linq2Xml exposes some similar functionality inline.
XSLT, however, can be a powerful way to separate data from presentation in your apps.
I am very interested in F# and some of the other new languages in the CLR/DLR. The DLR languages might be a lot better for your UI, because they don't make you cast a lot of stupid things.
However, I think that it is important to keep in mind tha learning a new language, especially in a new area, like functional programming, is always a good way to re-train your mind so that you are exposed to new concepts and you can code better in your language of choice, even if you never use those new languages.
Check out Boo - it runs on top of the .NET stack, but its syntax is more like Python.
To learn a new language that complements C#, I'd go with C++. You can use it in a 'way better than p/invoke' style to get access to unmanaged code from your C# apps. You can then start using it to write the memory-constrained apps, and/or performance-critical bits in, if you find some of your .NET applications start hogging all the RAM and/or CPU or just generally aren't as fast as you'd like.